1 // 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.
5 #ifndef V8_MIPS_LITHIUM_MIPS_H_
6 #define V8_MIPS_LITHIUM_MIPS_H_
8 #include "src/hydrogen.h"
9 #include "src/lithium.h"
10 #include "src/lithium-allocator.h"
11 #include "src/safepoint-table.h"
12 #include "src/utils.h"
17 // Forward declarations.
20 #define LITHIUM_CONCRETE_INSTRUCTION_LIST(V) \
21 V(AccessArgumentsAt) \
24 V(AllocateBlockContext) \
26 V(ArgumentsElements) \
34 V(CallWithDescriptor) \
40 V(CheckArrayBufferNotNeutered) \
41 V(CheckInstanceType) \
50 V(ClassOfTestAndBranch) \
51 V(CompareMinusZeroAndBranch) \
52 V(CompareNumericAndBranch) \
53 V(CmpObjectEqAndBranch) \
77 V(FlooringDivByConstI) \
78 V(FlooringDivByPowerOf2I) \
83 V(GetCachedArrayIndex) \
85 V(HasCachedArrayIndexAndBranch) \
86 V(HasInstanceTypeAndBranch) \
87 V(InnerAllocatedObject) \
89 V(InstanceOfKnownGlobal) \
91 V(Integer32ToDouble) \
93 V(IsConstructCallAndBranch) \
94 V(IsObjectAndBranch) \
95 V(IsStringAndBranch) \
97 V(IsUndetectableAndBranch) \
102 V(LoadFieldByIndex) \
103 V(LoadFunctionPrototype) \
104 V(LoadGlobalGeneric) \
106 V(LoadKeyedGeneric) \
108 V(LoadNamedGeneric) \
120 V(MaybeGrowElements) \
135 V(SeqStringGetChar) \
136 V(SeqStringSetChar) \
142 V(StoreContextSlot) \
143 V(StoreFrameContext) \
145 V(StoreKeyedGeneric) \
147 V(StoreNamedGeneric) \
149 V(StringCharCodeAt) \
150 V(StringCharFromCode) \
151 V(StringCompareAndBranch) \
155 V(ToFastProperties) \
156 V(TransitionElementsKind) \
157 V(TrapAllocationMemento) \
159 V(TypeofIsAndBranch) \
164 #define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic) \
165 Opcode opcode() const final { return LInstruction::k##type; } \
166 void CompileToNative(LCodeGen* generator) final; \
167 const char* Mnemonic() const final { return mnemonic; } \
168 static L##type* cast(LInstruction* instr) { \
169 DCHECK(instr->Is##type()); \
170 return reinterpret_cast<L##type*>(instr); \
174 #define DECLARE_HYDROGEN_ACCESSOR(type) \
175 H##type* hydrogen() const { \
176 return H##type::cast(hydrogen_value()); \
180 class LInstruction : public ZoneObject {
183 : environment_(NULL),
184 hydrogen_value_(NULL),
185 bit_field_(IsCallBits::encode(false)) {
188 virtual ~LInstruction() {}
190 virtual void CompileToNative(LCodeGen* generator) = 0;
191 virtual const char* Mnemonic() const = 0;
192 virtual void PrintTo(StringStream* stream);
193 virtual void PrintDataTo(StringStream* stream);
194 virtual void PrintOutputOperandTo(StringStream* stream);
197 // Declare a unique enum value for each instruction.
198 #define DECLARE_OPCODE(type) k##type,
199 LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_OPCODE)
200 kNumberOfInstructions
201 #undef DECLARE_OPCODE
204 virtual Opcode opcode() const = 0;
206 // Declare non-virtual type testers for all leaf IR classes.
207 #define DECLARE_PREDICATE(type) \
208 bool Is##type() const { return opcode() == k##type; }
209 LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_PREDICATE)
210 #undef DECLARE_PREDICATE
212 // Declare virtual predicates for instructions that don't have
214 virtual bool IsGap() const { return false; }
216 virtual bool IsControl() const { return false; }
218 // Try deleting this instruction if possible.
219 virtual bool TryDelete() { return false; }
221 void set_environment(LEnvironment* env) { environment_ = env; }
222 LEnvironment* environment() const { return environment_; }
223 bool HasEnvironment() const { return environment_ != NULL; }
225 void set_pointer_map(LPointerMap* p) { pointer_map_.set(p); }
226 LPointerMap* pointer_map() const { return pointer_map_.get(); }
227 bool HasPointerMap() const { return pointer_map_.is_set(); }
229 void set_hydrogen_value(HValue* value) { hydrogen_value_ = value; }
230 HValue* hydrogen_value() const { return hydrogen_value_; }
232 virtual void SetDeferredLazyDeoptimizationEnvironment(LEnvironment* env) { }
234 void MarkAsCall() { bit_field_ = IsCallBits::update(bit_field_, true); }
235 bool IsCall() const { return IsCallBits::decode(bit_field_); }
237 // Interface to the register allocator and iterators.
238 bool ClobbersTemps() const { return IsCall(); }
239 bool ClobbersRegisters() const { return IsCall(); }
240 virtual bool ClobbersDoubleRegisters(Isolate* isolate) const {
244 // Interface to the register allocator and iterators.
245 bool IsMarkedAsCall() const { return IsCall(); }
247 virtual bool HasResult() const = 0;
248 virtual LOperand* result() const = 0;
250 LOperand* FirstInput() { return InputAt(0); }
251 LOperand* Output() { return HasResult() ? result() : NULL; }
253 virtual bool HasInterestingComment(LCodeGen* gen) const { return true; }
259 virtual int InputCount() = 0;
260 virtual LOperand* InputAt(int i) = 0;
263 // Iterator interface.
264 friend class InputIterator;
266 friend class TempIterator;
267 virtual int TempCount() = 0;
268 virtual LOperand* TempAt(int i) = 0;
270 class IsCallBits: public BitField<bool, 0, 1> {};
272 LEnvironment* environment_;
273 SetOncePointer<LPointerMap> pointer_map_;
274 HValue* hydrogen_value_;
279 // R = number of result operands (0 or 1).
281 class LTemplateResultInstruction : public LInstruction {
283 // Allow 0 or 1 output operands.
284 STATIC_ASSERT(R == 0 || R == 1);
285 bool HasResult() const final { return R != 0 && result() != NULL; }
286 void set_result(LOperand* operand) { results_[0] = operand; }
287 LOperand* result() const override { return results_[0]; }
290 EmbeddedContainer<LOperand*, R> results_;
294 // R = number of result operands (0 or 1).
295 // I = number of input operands.
296 // T = number of temporary operands.
297 template<int R, int I, int T>
298 class LTemplateInstruction : public LTemplateResultInstruction<R> {
300 EmbeddedContainer<LOperand*, I> inputs_;
301 EmbeddedContainer<LOperand*, T> temps_;
305 int InputCount() final { return I; }
306 LOperand* InputAt(int i) final { return inputs_[i]; }
308 int TempCount() final { return T; }
309 LOperand* TempAt(int i) final { return temps_[i]; }
313 class LGap : public LTemplateInstruction<0, 0, 0> {
315 explicit LGap(HBasicBlock* block)
317 parallel_moves_[BEFORE] = NULL;
318 parallel_moves_[START] = NULL;
319 parallel_moves_[END] = NULL;
320 parallel_moves_[AFTER] = NULL;
323 // Can't use the DECLARE-macro here because of sub-classes.
324 bool IsGap() const final { return true; }
325 void PrintDataTo(StringStream* stream) override;
326 static LGap* cast(LInstruction* instr) {
327 DCHECK(instr->IsGap());
328 return reinterpret_cast<LGap*>(instr);
331 bool IsRedundant() const;
333 HBasicBlock* block() const { return block_; }
340 FIRST_INNER_POSITION = BEFORE,
341 LAST_INNER_POSITION = AFTER
344 LParallelMove* GetOrCreateParallelMove(InnerPosition pos, Zone* zone) {
345 if (parallel_moves_[pos] == NULL) {
346 parallel_moves_[pos] = new(zone) LParallelMove(zone);
348 return parallel_moves_[pos];
351 LParallelMove* GetParallelMove(InnerPosition pos) {
352 return parallel_moves_[pos];
356 LParallelMove* parallel_moves_[LAST_INNER_POSITION + 1];
361 class LInstructionGap final : public LGap {
363 explicit LInstructionGap(HBasicBlock* block) : LGap(block) { }
365 bool HasInterestingComment(LCodeGen* gen) const override {
366 return !IsRedundant();
369 DECLARE_CONCRETE_INSTRUCTION(InstructionGap, "gap")
373 class LGoto final : public LTemplateInstruction<0, 0, 0> {
375 explicit LGoto(HBasicBlock* block) : block_(block) { }
377 bool HasInterestingComment(LCodeGen* gen) const override;
378 DECLARE_CONCRETE_INSTRUCTION(Goto, "goto")
379 void PrintDataTo(StringStream* stream) override;
380 bool IsControl() const override { return true; }
382 int block_id() const { return block_->block_id(); }
389 class LLazyBailout final : public LTemplateInstruction<0, 0, 0> {
391 LLazyBailout() : gap_instructions_size_(0) { }
393 DECLARE_CONCRETE_INSTRUCTION(LazyBailout, "lazy-bailout")
395 void set_gap_instructions_size(int gap_instructions_size) {
396 gap_instructions_size_ = gap_instructions_size;
398 int gap_instructions_size() { return gap_instructions_size_; }
401 int gap_instructions_size_;
405 class LDummy final : public LTemplateInstruction<1, 0, 0> {
408 DECLARE_CONCRETE_INSTRUCTION(Dummy, "dummy")
412 class LDummyUse final : public LTemplateInstruction<1, 1, 0> {
414 explicit LDummyUse(LOperand* value) {
417 DECLARE_CONCRETE_INSTRUCTION(DummyUse, "dummy-use")
421 class LDeoptimize final : public LTemplateInstruction<0, 0, 0> {
423 bool IsControl() const override { return true; }
424 DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize")
425 DECLARE_HYDROGEN_ACCESSOR(Deoptimize)
429 class LLabel final : public LGap {
431 explicit LLabel(HBasicBlock* block)
432 : LGap(block), replacement_(NULL) { }
434 bool HasInterestingComment(LCodeGen* gen) const override { return false; }
435 DECLARE_CONCRETE_INSTRUCTION(Label, "label")
437 void PrintDataTo(StringStream* stream) override;
439 int block_id() const { return block()->block_id(); }
440 bool is_loop_header() const { return block()->IsLoopHeader(); }
441 bool is_osr_entry() const { return block()->is_osr_entry(); }
442 Label* label() { return &label_; }
443 LLabel* replacement() const { return replacement_; }
444 void set_replacement(LLabel* label) { replacement_ = label; }
445 bool HasReplacement() const { return replacement_ != NULL; }
449 LLabel* replacement_;
453 class LParameter final : public LTemplateInstruction<1, 0, 0> {
455 bool HasInterestingComment(LCodeGen* gen) const override { return false; }
456 DECLARE_CONCRETE_INSTRUCTION(Parameter, "parameter")
460 class LCallStub final : public LTemplateInstruction<1, 1, 0> {
462 explicit LCallStub(LOperand* context) {
463 inputs_[0] = context;
466 LOperand* context() { return inputs_[0]; }
468 DECLARE_CONCRETE_INSTRUCTION(CallStub, "call-stub")
469 DECLARE_HYDROGEN_ACCESSOR(CallStub)
473 class LUnknownOSRValue final : public LTemplateInstruction<1, 0, 0> {
475 bool HasInterestingComment(LCodeGen* gen) const override { return false; }
476 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue, "unknown-osr-value")
480 template<int I, int T>
481 class LControlInstruction : public LTemplateInstruction<0, I, T> {
483 LControlInstruction() : false_label_(NULL), true_label_(NULL) { }
485 bool IsControl() const final { return true; }
487 int SuccessorCount() { return hydrogen()->SuccessorCount(); }
488 HBasicBlock* SuccessorAt(int i) { return hydrogen()->SuccessorAt(i); }
490 int TrueDestination(LChunk* chunk) {
491 return chunk->LookupDestination(true_block_id());
493 int FalseDestination(LChunk* chunk) {
494 return chunk->LookupDestination(false_block_id());
497 Label* TrueLabel(LChunk* chunk) {
498 if (true_label_ == NULL) {
499 true_label_ = chunk->GetAssemblyLabel(TrueDestination(chunk));
503 Label* FalseLabel(LChunk* chunk) {
504 if (false_label_ == NULL) {
505 false_label_ = chunk->GetAssemblyLabel(FalseDestination(chunk));
511 int true_block_id() { return SuccessorAt(0)->block_id(); }
512 int false_block_id() { return SuccessorAt(1)->block_id(); }
515 HControlInstruction* hydrogen() {
516 return HControlInstruction::cast(this->hydrogen_value());
524 class LWrapReceiver final : public LTemplateInstruction<1, 2, 0> {
526 LWrapReceiver(LOperand* receiver, LOperand* function) {
527 inputs_[0] = receiver;
528 inputs_[1] = function;
531 DECLARE_CONCRETE_INSTRUCTION(WrapReceiver, "wrap-receiver")
532 DECLARE_HYDROGEN_ACCESSOR(WrapReceiver)
534 LOperand* receiver() { return inputs_[0]; }
535 LOperand* function() { return inputs_[1]; }
539 class LApplyArguments final : public LTemplateInstruction<1, 4, 0> {
541 LApplyArguments(LOperand* function,
544 LOperand* elements) {
545 inputs_[0] = function;
546 inputs_[1] = receiver;
548 inputs_[3] = elements;
551 DECLARE_CONCRETE_INSTRUCTION(ApplyArguments, "apply-arguments")
553 LOperand* function() { return inputs_[0]; }
554 LOperand* receiver() { return inputs_[1]; }
555 LOperand* length() { return inputs_[2]; }
556 LOperand* elements() { return inputs_[3]; }
560 class LAccessArgumentsAt final : public LTemplateInstruction<1, 3, 0> {
562 LAccessArgumentsAt(LOperand* arguments, LOperand* length, LOperand* index) {
563 inputs_[0] = arguments;
568 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt, "access-arguments-at")
570 LOperand* arguments() { return inputs_[0]; }
571 LOperand* length() { return inputs_[1]; }
572 LOperand* index() { return inputs_[2]; }
574 void PrintDataTo(StringStream* stream) override;
578 class LArgumentsLength final : public LTemplateInstruction<1, 1, 0> {
580 explicit LArgumentsLength(LOperand* elements) {
581 inputs_[0] = elements;
584 LOperand* elements() { return inputs_[0]; }
586 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength, "arguments-length")
590 class LArgumentsElements final : public LTemplateInstruction<1, 0, 0> {
592 DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements, "arguments-elements")
593 DECLARE_HYDROGEN_ACCESSOR(ArgumentsElements)
597 class LModByPowerOf2I final : public LTemplateInstruction<1, 1, 0> {
599 LModByPowerOf2I(LOperand* dividend, int32_t divisor) {
600 inputs_[0] = dividend;
604 LOperand* dividend() { return inputs_[0]; }
605 int32_t divisor() const { return divisor_; }
607 DECLARE_CONCRETE_INSTRUCTION(ModByPowerOf2I, "mod-by-power-of-2-i")
608 DECLARE_HYDROGEN_ACCESSOR(Mod)
615 class LModByConstI final : public LTemplateInstruction<1, 1, 0> {
617 LModByConstI(LOperand* dividend, int32_t divisor) {
618 inputs_[0] = dividend;
622 LOperand* dividend() { return inputs_[0]; }
623 int32_t divisor() const { return divisor_; }
625 DECLARE_CONCRETE_INSTRUCTION(ModByConstI, "mod-by-const-i")
626 DECLARE_HYDROGEN_ACCESSOR(Mod)
633 class LModI final : public LTemplateInstruction<1, 2, 3> {
635 LModI(LOperand* left,
641 LOperand* left() { return inputs_[0]; }
642 LOperand* right() { return inputs_[1]; }
644 DECLARE_CONCRETE_INSTRUCTION(ModI, "mod-i")
645 DECLARE_HYDROGEN_ACCESSOR(Mod)
649 class LDivByPowerOf2I final : public LTemplateInstruction<1, 1, 0> {
651 LDivByPowerOf2I(LOperand* dividend, int32_t divisor) {
652 inputs_[0] = dividend;
656 LOperand* dividend() { return inputs_[0]; }
657 int32_t divisor() const { return divisor_; }
659 DECLARE_CONCRETE_INSTRUCTION(DivByPowerOf2I, "div-by-power-of-2-i")
660 DECLARE_HYDROGEN_ACCESSOR(Div)
667 class LDivByConstI final : public LTemplateInstruction<1, 1, 0> {
669 LDivByConstI(LOperand* dividend, int32_t divisor) {
670 inputs_[0] = dividend;
674 LOperand* dividend() { return inputs_[0]; }
675 int32_t divisor() const { return divisor_; }
677 DECLARE_CONCRETE_INSTRUCTION(DivByConstI, "div-by-const-i")
678 DECLARE_HYDROGEN_ACCESSOR(Div)
685 class LDivI final : public LTemplateInstruction<1, 2, 1> {
687 LDivI(LOperand* dividend, LOperand* divisor, LOperand* temp) {
688 inputs_[0] = dividend;
689 inputs_[1] = divisor;
693 LOperand* dividend() { return inputs_[0]; }
694 LOperand* divisor() { return inputs_[1]; }
695 LOperand* temp() { return temps_[0]; }
697 DECLARE_CONCRETE_INSTRUCTION(DivI, "div-i")
698 DECLARE_HYDROGEN_ACCESSOR(BinaryOperation)
702 class LFlooringDivByPowerOf2I final : public LTemplateInstruction<1, 1, 0> {
704 LFlooringDivByPowerOf2I(LOperand* dividend, int32_t divisor) {
705 inputs_[0] = dividend;
709 LOperand* dividend() { return inputs_[0]; }
710 int32_t divisor() { return divisor_; }
712 DECLARE_CONCRETE_INSTRUCTION(FlooringDivByPowerOf2I,
713 "flooring-div-by-power-of-2-i")
714 DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv)
721 class LFlooringDivByConstI final : public LTemplateInstruction<1, 1, 2> {
723 LFlooringDivByConstI(LOperand* dividend, int32_t divisor, LOperand* temp) {
724 inputs_[0] = dividend;
729 LOperand* dividend() { return inputs_[0]; }
730 int32_t divisor() const { return divisor_; }
731 LOperand* temp() { return temps_[0]; }
733 DECLARE_CONCRETE_INSTRUCTION(FlooringDivByConstI, "flooring-div-by-const-i")
734 DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv)
741 class LFlooringDivI final : public LTemplateInstruction<1, 2, 0> {
743 LFlooringDivI(LOperand* dividend, LOperand* divisor) {
744 inputs_[0] = dividend;
745 inputs_[1] = divisor;
748 LOperand* dividend() { return inputs_[0]; }
749 LOperand* divisor() { return inputs_[1]; }
751 DECLARE_CONCRETE_INSTRUCTION(FlooringDivI, "flooring-div-i")
752 DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv)
756 class LMulI final : public LTemplateInstruction<1, 2, 0> {
758 LMulI(LOperand* left, LOperand* right) {
763 LOperand* left() { return inputs_[0]; }
764 LOperand* right() { return inputs_[1]; }
766 DECLARE_CONCRETE_INSTRUCTION(MulI, "mul-i")
767 DECLARE_HYDROGEN_ACCESSOR(Mul)
771 // Instruction for computing multiplier * multiplicand + addend.
772 class LMultiplyAddD final : public LTemplateInstruction<1, 3, 0> {
774 LMultiplyAddD(LOperand* addend, LOperand* multiplier,
775 LOperand* multiplicand) {
777 inputs_[1] = multiplier;
778 inputs_[2] = multiplicand;
781 LOperand* addend() { return inputs_[0]; }
782 LOperand* multiplier() { return inputs_[1]; }
783 LOperand* multiplicand() { return inputs_[2]; }
785 DECLARE_CONCRETE_INSTRUCTION(MultiplyAddD, "multiply-add-d")
789 class LDebugBreak final : public LTemplateInstruction<0, 0, 0> {
791 DECLARE_CONCRETE_INSTRUCTION(DebugBreak, "break")
795 class LCompareNumericAndBranch final : public LControlInstruction<2, 0> {
797 LCompareNumericAndBranch(LOperand* left, LOperand* right) {
802 LOperand* left() { return inputs_[0]; }
803 LOperand* right() { return inputs_[1]; }
805 DECLARE_CONCRETE_INSTRUCTION(CompareNumericAndBranch,
806 "compare-numeric-and-branch")
807 DECLARE_HYDROGEN_ACCESSOR(CompareNumericAndBranch)
809 Token::Value op() const { return hydrogen()->token(); }
810 bool is_double() const {
811 return hydrogen()->representation().IsDouble();
814 void PrintDataTo(StringStream* stream) override;
818 class LMathFloor final : public LTemplateInstruction<1, 1, 1> {
820 LMathFloor(LOperand* value, LOperand* temp) {
825 LOperand* value() { return inputs_[0]; }
826 LOperand* temp() { return temps_[0]; }
828 DECLARE_CONCRETE_INSTRUCTION(MathFloor, "math-floor")
829 DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation)
833 class LMathRound final : public LTemplateInstruction<1, 1, 1> {
835 LMathRound(LOperand* value, LOperand* temp) {
840 LOperand* value() { return inputs_[0]; }
841 LOperand* temp() { return temps_[0]; }
843 DECLARE_CONCRETE_INSTRUCTION(MathRound, "math-round")
844 DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation)
848 class LMathFround final : public LTemplateInstruction<1, 1, 0> {
850 explicit LMathFround(LOperand* value) { inputs_[0] = value; }
852 LOperand* value() { return inputs_[0]; }
854 DECLARE_CONCRETE_INSTRUCTION(MathFround, "math-fround")
858 class LMathAbs final : public LTemplateInstruction<1, 2, 0> {
860 LMathAbs(LOperand* context, LOperand* value) {
861 inputs_[1] = context;
865 LOperand* context() { return inputs_[1]; }
866 LOperand* value() { return inputs_[0]; }
868 DECLARE_CONCRETE_INSTRUCTION(MathAbs, "math-abs")
869 DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation)
873 class LMathLog final : public LTemplateInstruction<1, 1, 0> {
875 explicit LMathLog(LOperand* value) {
879 LOperand* value() { return inputs_[0]; }
881 DECLARE_CONCRETE_INSTRUCTION(MathLog, "math-log")
885 class LMathClz32 final : public LTemplateInstruction<1, 1, 0> {
887 explicit LMathClz32(LOperand* value) {
891 LOperand* value() { return inputs_[0]; }
893 DECLARE_CONCRETE_INSTRUCTION(MathClz32, "math-clz32")
897 class LMathExp final : public LTemplateInstruction<1, 1, 3> {
899 LMathExp(LOperand* value,
900 LOperand* double_temp,
906 temps_[2] = double_temp;
907 ExternalReference::InitializeMathExpData();
910 LOperand* value() { return inputs_[0]; }
911 LOperand* temp1() { return temps_[0]; }
912 LOperand* temp2() { return temps_[1]; }
913 LOperand* double_temp() { return temps_[2]; }
915 DECLARE_CONCRETE_INSTRUCTION(MathExp, "math-exp")
919 class LMathSqrt final : public LTemplateInstruction<1, 1, 0> {
921 explicit LMathSqrt(LOperand* value) {
925 LOperand* value() { return inputs_[0]; }
927 DECLARE_CONCRETE_INSTRUCTION(MathSqrt, "math-sqrt")
931 class LMathPowHalf final : public LTemplateInstruction<1, 1, 1> {
933 LMathPowHalf(LOperand* value, LOperand* temp) {
938 LOperand* value() { return inputs_[0]; }
939 LOperand* temp() { return temps_[0]; }
941 DECLARE_CONCRETE_INSTRUCTION(MathPowHalf, "math-pow-half")
945 class LCmpObjectEqAndBranch final : public LControlInstruction<2, 0> {
947 LCmpObjectEqAndBranch(LOperand* left, LOperand* right) {
952 LOperand* left() { return inputs_[0]; }
953 LOperand* right() { return inputs_[1]; }
955 DECLARE_CONCRETE_INSTRUCTION(CmpObjectEqAndBranch, "cmp-object-eq-and-branch")
956 DECLARE_HYDROGEN_ACCESSOR(CompareObjectEqAndBranch)
960 class LCmpHoleAndBranch final : public LControlInstruction<1, 0> {
962 explicit LCmpHoleAndBranch(LOperand* object) {
966 LOperand* object() { return inputs_[0]; }
968 DECLARE_CONCRETE_INSTRUCTION(CmpHoleAndBranch, "cmp-hole-and-branch")
969 DECLARE_HYDROGEN_ACCESSOR(CompareHoleAndBranch)
973 class LCompareMinusZeroAndBranch final : public LControlInstruction<1, 1> {
975 LCompareMinusZeroAndBranch(LOperand* value, LOperand* temp) {
980 LOperand* value() { return inputs_[0]; }
981 LOperand* temp() { return temps_[0]; }
983 DECLARE_CONCRETE_INSTRUCTION(CompareMinusZeroAndBranch,
984 "cmp-minus-zero-and-branch")
985 DECLARE_HYDROGEN_ACCESSOR(CompareMinusZeroAndBranch)
989 class LIsObjectAndBranch final : public LControlInstruction<1, 1> {
991 LIsObjectAndBranch(LOperand* value, LOperand* temp) {
996 LOperand* value() { return inputs_[0]; }
997 LOperand* temp() { return temps_[0]; }
999 DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch, "is-object-and-branch")
1000 DECLARE_HYDROGEN_ACCESSOR(IsObjectAndBranch)
1002 void PrintDataTo(StringStream* stream) override;
1006 class LIsStringAndBranch final : public LControlInstruction<1, 1> {
1008 LIsStringAndBranch(LOperand* value, LOperand* temp) {
1013 LOperand* value() { return inputs_[0]; }
1014 LOperand* temp() { return temps_[0]; }
1016 DECLARE_CONCRETE_INSTRUCTION(IsStringAndBranch, "is-string-and-branch")
1017 DECLARE_HYDROGEN_ACCESSOR(IsStringAndBranch)
1019 void PrintDataTo(StringStream* stream) override;
1023 class LIsSmiAndBranch final : public LControlInstruction<1, 0> {
1025 explicit LIsSmiAndBranch(LOperand* value) {
1029 LOperand* value() { return inputs_[0]; }
1031 DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch, "is-smi-and-branch")
1032 DECLARE_HYDROGEN_ACCESSOR(IsSmiAndBranch)
1034 void PrintDataTo(StringStream* stream) override;
1038 class LIsUndetectableAndBranch final : public LControlInstruction<1, 1> {
1040 explicit LIsUndetectableAndBranch(LOperand* value, LOperand* temp) {
1045 LOperand* value() { return inputs_[0]; }
1046 LOperand* temp() { return temps_[0]; }
1048 DECLARE_CONCRETE_INSTRUCTION(IsUndetectableAndBranch,
1049 "is-undetectable-and-branch")
1050 DECLARE_HYDROGEN_ACCESSOR(IsUndetectableAndBranch)
1052 void PrintDataTo(StringStream* stream) override;
1056 class LStringCompareAndBranch final : public LControlInstruction<3, 0> {
1058 LStringCompareAndBranch(LOperand* context, LOperand* left, LOperand* right) {
1059 inputs_[0] = context;
1064 LOperand* context() { return inputs_[0]; }
1065 LOperand* left() { return inputs_[1]; }
1066 LOperand* right() { return inputs_[2]; }
1068 DECLARE_CONCRETE_INSTRUCTION(StringCompareAndBranch,
1069 "string-compare-and-branch")
1070 DECLARE_HYDROGEN_ACCESSOR(StringCompareAndBranch)
1072 Token::Value op() const { return hydrogen()->token(); }
1074 void PrintDataTo(StringStream* stream) override;
1078 class LHasInstanceTypeAndBranch final : public LControlInstruction<1, 0> {
1080 explicit LHasInstanceTypeAndBranch(LOperand* value) {
1084 LOperand* value() { return inputs_[0]; }
1086 DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch,
1087 "has-instance-type-and-branch")
1088 DECLARE_HYDROGEN_ACCESSOR(HasInstanceTypeAndBranch)
1090 void PrintDataTo(StringStream* stream) override;
1094 class LGetCachedArrayIndex final : public LTemplateInstruction<1, 1, 0> {
1096 explicit LGetCachedArrayIndex(LOperand* value) {
1100 LOperand* value() { return inputs_[0]; }
1102 DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex, "get-cached-array-index")
1103 DECLARE_HYDROGEN_ACCESSOR(GetCachedArrayIndex)
1107 class LHasCachedArrayIndexAndBranch final : public LControlInstruction<1, 0> {
1109 explicit LHasCachedArrayIndexAndBranch(LOperand* value) {
1113 LOperand* value() { return inputs_[0]; }
1115 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndexAndBranch,
1116 "has-cached-array-index-and-branch")
1117 DECLARE_HYDROGEN_ACCESSOR(HasCachedArrayIndexAndBranch)
1119 void PrintDataTo(StringStream* stream) override;
1123 class LClassOfTestAndBranch final : public LControlInstruction<1, 1> {
1125 LClassOfTestAndBranch(LOperand* value, LOperand* temp) {
1130 LOperand* value() { return inputs_[0]; }
1131 LOperand* temp() { return temps_[0]; }
1133 DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch,
1134 "class-of-test-and-branch")
1135 DECLARE_HYDROGEN_ACCESSOR(ClassOfTestAndBranch)
1137 void PrintDataTo(StringStream* stream) override;
1141 class LCmpT final : public LTemplateInstruction<1, 3, 0> {
1143 LCmpT(LOperand* context, LOperand* left, LOperand* right) {
1144 inputs_[0] = context;
1149 LOperand* context() { return inputs_[0]; }
1150 LOperand* left() { return inputs_[1]; }
1151 LOperand* right() { return inputs_[2]; }
1153 DECLARE_CONCRETE_INSTRUCTION(CmpT, "cmp-t")
1154 DECLARE_HYDROGEN_ACCESSOR(CompareGeneric)
1156 Strength strength() { return hydrogen()->strength(); }
1158 Token::Value op() const { return hydrogen()->token(); }
1162 class LInstanceOf final : public LTemplateInstruction<1, 3, 0> {
1164 LInstanceOf(LOperand* context, LOperand* left, LOperand* right) {
1165 inputs_[0] = context;
1170 LOperand* context() { return inputs_[0]; }
1171 LOperand* left() { return inputs_[1]; }
1172 LOperand* right() { return inputs_[2]; }
1174 DECLARE_CONCRETE_INSTRUCTION(InstanceOf, "instance-of")
1178 class LInstanceOfKnownGlobal final : public LTemplateInstruction<1, 2, 1> {
1180 LInstanceOfKnownGlobal(LOperand* context, LOperand* value, LOperand* temp) {
1181 inputs_[0] = context;
1186 LOperand* context() { return inputs_[0]; }
1187 LOperand* value() { return inputs_[1]; }
1188 LOperand* temp() { return temps_[0]; }
1190 DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal,
1191 "instance-of-known-global")
1192 DECLARE_HYDROGEN_ACCESSOR(InstanceOfKnownGlobal)
1194 Handle<JSFunction> function() const { return hydrogen()->function(); }
1195 LEnvironment* GetDeferredLazyDeoptimizationEnvironment() {
1196 return lazy_deopt_env_;
1198 virtual void SetDeferredLazyDeoptimizationEnvironment(
1199 LEnvironment* env) override {
1200 lazy_deopt_env_ = env;
1204 LEnvironment* lazy_deopt_env_;
1208 class LBoundsCheck final : public LTemplateInstruction<0, 2, 0> {
1210 LBoundsCheck(LOperand* index, LOperand* length) {
1212 inputs_[1] = length;
1215 LOperand* index() { return inputs_[0]; }
1216 LOperand* length() { return inputs_[1]; }
1218 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck, "bounds-check")
1219 DECLARE_HYDROGEN_ACCESSOR(BoundsCheck)
1223 class LBitI final : public LTemplateInstruction<1, 2, 0> {
1225 LBitI(LOperand* left, LOperand* right) {
1230 LOperand* left() { return inputs_[0]; }
1231 LOperand* right() { return inputs_[1]; }
1233 Token::Value op() const { return hydrogen()->op(); }
1235 DECLARE_CONCRETE_INSTRUCTION(BitI, "bit-i")
1236 DECLARE_HYDROGEN_ACCESSOR(Bitwise)
1240 class LShiftI final : public LTemplateInstruction<1, 2, 0> {
1242 LShiftI(Token::Value op, LOperand* left, LOperand* right, bool can_deopt)
1243 : op_(op), can_deopt_(can_deopt) {
1248 Token::Value op() const { return op_; }
1249 LOperand* left() { return inputs_[0]; }
1250 LOperand* right() { return inputs_[1]; }
1251 bool can_deopt() const { return can_deopt_; }
1253 DECLARE_CONCRETE_INSTRUCTION(ShiftI, "shift-i")
1261 class LSubI final : public LTemplateInstruction<1, 2, 0> {
1263 LSubI(LOperand* left, LOperand* right) {
1268 LOperand* left() { return inputs_[0]; }
1269 LOperand* right() { return inputs_[1]; }
1271 DECLARE_CONCRETE_INSTRUCTION(SubI, "sub-i")
1272 DECLARE_HYDROGEN_ACCESSOR(Sub)
1276 class LConstantI final : public LTemplateInstruction<1, 0, 0> {
1278 DECLARE_CONCRETE_INSTRUCTION(ConstantI, "constant-i")
1279 DECLARE_HYDROGEN_ACCESSOR(Constant)
1281 int32_t value() const { return hydrogen()->Integer32Value(); }
1285 class LConstantS final : public LTemplateInstruction<1, 0, 0> {
1287 DECLARE_CONCRETE_INSTRUCTION(ConstantS, "constant-s")
1288 DECLARE_HYDROGEN_ACCESSOR(Constant)
1290 Smi* value() const { return Smi::FromInt(hydrogen()->Integer32Value()); }
1294 class LConstantD final : public LTemplateInstruction<1, 0, 0> {
1296 DECLARE_CONCRETE_INSTRUCTION(ConstantD, "constant-d")
1297 DECLARE_HYDROGEN_ACCESSOR(Constant)
1299 double value() const { return hydrogen()->DoubleValue(); }
1303 class LConstantE final : public LTemplateInstruction<1, 0, 0> {
1305 DECLARE_CONCRETE_INSTRUCTION(ConstantE, "constant-e")
1306 DECLARE_HYDROGEN_ACCESSOR(Constant)
1308 ExternalReference value() const {
1309 return hydrogen()->ExternalReferenceValue();
1314 class LConstantT final : public LTemplateInstruction<1, 0, 0> {
1316 DECLARE_CONCRETE_INSTRUCTION(ConstantT, "constant-t")
1317 DECLARE_HYDROGEN_ACCESSOR(Constant)
1319 Handle<Object> value(Isolate* isolate) const {
1320 return hydrogen()->handle(isolate);
1325 class LBranch final : public LControlInstruction<1, 0> {
1327 explicit LBranch(LOperand* value) {
1331 LOperand* value() { return inputs_[0]; }
1333 DECLARE_CONCRETE_INSTRUCTION(Branch, "branch")
1334 DECLARE_HYDROGEN_ACCESSOR(Branch)
1336 void PrintDataTo(StringStream* stream) override;
1340 class LCmpMapAndBranch final : public LControlInstruction<1, 1> {
1342 LCmpMapAndBranch(LOperand* value, LOperand* temp) {
1347 LOperand* value() { return inputs_[0]; }
1348 LOperand* temp() { return temps_[0]; }
1350 DECLARE_CONCRETE_INSTRUCTION(CmpMapAndBranch, "cmp-map-and-branch")
1351 DECLARE_HYDROGEN_ACCESSOR(CompareMap)
1353 Handle<Map> map() const { return hydrogen()->map().handle(); }
1357 class LMapEnumLength final : public LTemplateInstruction<1, 1, 0> {
1359 explicit LMapEnumLength(LOperand* value) {
1363 LOperand* value() { return inputs_[0]; }
1365 DECLARE_CONCRETE_INSTRUCTION(MapEnumLength, "map-enum-length")
1369 class LDateField final : public LTemplateInstruction<1, 1, 1> {
1371 LDateField(LOperand* date, LOperand* temp, Smi* index) : index_(index) {
1376 LOperand* date() { return inputs_[0]; }
1377 LOperand* temp() { return temps_[0]; }
1378 Smi* index() const { return index_; }
1380 DECLARE_CONCRETE_INSTRUCTION(DateField, "date-field")
1381 DECLARE_HYDROGEN_ACCESSOR(DateField)
1388 class LSeqStringGetChar final : public LTemplateInstruction<1, 2, 0> {
1390 LSeqStringGetChar(LOperand* string, LOperand* index) {
1391 inputs_[0] = string;
1395 LOperand* string() const { return inputs_[0]; }
1396 LOperand* index() const { return inputs_[1]; }
1398 DECLARE_CONCRETE_INSTRUCTION(SeqStringGetChar, "seq-string-get-char")
1399 DECLARE_HYDROGEN_ACCESSOR(SeqStringGetChar)
1403 class LSeqStringSetChar final : public LTemplateInstruction<1, 4, 0> {
1405 LSeqStringSetChar(LOperand* context,
1409 inputs_[0] = context;
1410 inputs_[1] = string;
1415 LOperand* string() { return inputs_[1]; }
1416 LOperand* index() { return inputs_[2]; }
1417 LOperand* value() { return inputs_[3]; }
1419 DECLARE_CONCRETE_INSTRUCTION(SeqStringSetChar, "seq-string-set-char")
1420 DECLARE_HYDROGEN_ACCESSOR(SeqStringSetChar)
1424 class LAddI final : public LTemplateInstruction<1, 2, 0> {
1426 LAddI(LOperand* left, LOperand* right) {
1431 LOperand* left() { return inputs_[0]; }
1432 LOperand* right() { return inputs_[1]; }
1434 DECLARE_CONCRETE_INSTRUCTION(AddI, "add-i")
1435 DECLARE_HYDROGEN_ACCESSOR(Add)
1439 class LMathMinMax final : public LTemplateInstruction<1, 2, 0> {
1441 LMathMinMax(LOperand* left, LOperand* right) {
1446 LOperand* left() { return inputs_[0]; }
1447 LOperand* right() { return inputs_[1]; }
1449 DECLARE_CONCRETE_INSTRUCTION(MathMinMax, "math-min-max")
1450 DECLARE_HYDROGEN_ACCESSOR(MathMinMax)
1454 class LPower final : public LTemplateInstruction<1, 2, 0> {
1456 LPower(LOperand* left, LOperand* right) {
1461 LOperand* left() { return inputs_[0]; }
1462 LOperand* right() { return inputs_[1]; }
1464 DECLARE_CONCRETE_INSTRUCTION(Power, "power")
1465 DECLARE_HYDROGEN_ACCESSOR(Power)
1469 class LArithmeticD final : public LTemplateInstruction<1, 2, 0> {
1471 LArithmeticD(Token::Value op, LOperand* left, LOperand* right)
1477 Token::Value op() const { return op_; }
1478 LOperand* left() { return inputs_[0]; }
1479 LOperand* right() { return inputs_[1]; }
1481 Opcode opcode() const override { return LInstruction::kArithmeticD; }
1482 void CompileToNative(LCodeGen* generator) override;
1483 const char* Mnemonic() const override;
1490 class LArithmeticT final : public LTemplateInstruction<1, 3, 0> {
1492 LArithmeticT(Token::Value op,
1497 inputs_[0] = context;
1502 LOperand* context() { return inputs_[0]; }
1503 LOperand* left() { return inputs_[1]; }
1504 LOperand* right() { return inputs_[2]; }
1505 Token::Value op() const { return op_; }
1507 Opcode opcode() const final { return LInstruction::kArithmeticT; }
1508 void CompileToNative(LCodeGen* generator) override;
1509 const char* Mnemonic() const override;
1511 DECLARE_HYDROGEN_ACCESSOR(BinaryOperation)
1513 Strength strength() { return hydrogen()->strength(); }
1520 class LReturn final : public LTemplateInstruction<0, 3, 0> {
1522 LReturn(LOperand* value, LOperand* context, LOperand* parameter_count) {
1524 inputs_[1] = context;
1525 inputs_[2] = parameter_count;
1528 LOperand* value() { return inputs_[0]; }
1530 bool has_constant_parameter_count() {
1531 return parameter_count()->IsConstantOperand();
1533 LConstantOperand* constant_parameter_count() {
1534 DCHECK(has_constant_parameter_count());
1535 return LConstantOperand::cast(parameter_count());
1537 LOperand* parameter_count() { return inputs_[2]; }
1539 DECLARE_CONCRETE_INSTRUCTION(Return, "return")
1543 class LLoadNamedField final : public LTemplateInstruction<1, 1, 0> {
1545 explicit LLoadNamedField(LOperand* object) {
1546 inputs_[0] = object;
1549 LOperand* object() { return inputs_[0]; }
1551 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load-named-field")
1552 DECLARE_HYDROGEN_ACCESSOR(LoadNamedField)
1556 class LLoadNamedGeneric final : public LTemplateInstruction<1, 2, 1> {
1558 LLoadNamedGeneric(LOperand* context, LOperand* object, LOperand* vector) {
1559 inputs_[0] = context;
1560 inputs_[1] = object;
1564 LOperand* context() { return inputs_[0]; }
1565 LOperand* object() { return inputs_[1]; }
1566 LOperand* temp_vector() { return temps_[0]; }
1568 DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric, "load-named-generic")
1569 DECLARE_HYDROGEN_ACCESSOR(LoadNamedGeneric)
1571 Handle<Object> name() const { return hydrogen()->name(); }
1575 class LLoadFunctionPrototype final : public LTemplateInstruction<1, 1, 0> {
1577 explicit LLoadFunctionPrototype(LOperand* function) {
1578 inputs_[0] = function;
1581 LOperand* function() { return inputs_[0]; }
1583 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype, "load-function-prototype")
1584 DECLARE_HYDROGEN_ACCESSOR(LoadFunctionPrototype)
1588 class LLoadRoot final : public LTemplateInstruction<1, 0, 0> {
1590 DECLARE_CONCRETE_INSTRUCTION(LoadRoot, "load-root")
1591 DECLARE_HYDROGEN_ACCESSOR(LoadRoot)
1593 Heap::RootListIndex index() const { return hydrogen()->index(); }
1597 class LLoadKeyed final : public LTemplateInstruction<1, 2, 0> {
1599 LLoadKeyed(LOperand* elements, LOperand* key) {
1600 inputs_[0] = elements;
1604 LOperand* elements() { return inputs_[0]; }
1605 LOperand* key() { return inputs_[1]; }
1606 ElementsKind elements_kind() const {
1607 return hydrogen()->elements_kind();
1609 bool is_external() const {
1610 return hydrogen()->is_external();
1612 bool is_fixed_typed_array() const {
1613 return hydrogen()->is_fixed_typed_array();
1615 bool is_typed_elements() const {
1616 return is_external() || is_fixed_typed_array();
1619 DECLARE_CONCRETE_INSTRUCTION(LoadKeyed, "load-keyed")
1620 DECLARE_HYDROGEN_ACCESSOR(LoadKeyed)
1622 void PrintDataTo(StringStream* stream) override;
1623 uint32_t base_offset() const { return hydrogen()->base_offset(); }
1627 class LLoadKeyedGeneric final : public LTemplateInstruction<1, 3, 1> {
1629 LLoadKeyedGeneric(LOperand* context, LOperand* object, LOperand* key,
1631 inputs_[0] = context;
1632 inputs_[1] = object;
1637 LOperand* context() { return inputs_[0]; }
1638 LOperand* object() { return inputs_[1]; }
1639 LOperand* key() { return inputs_[2]; }
1640 LOperand* temp_vector() { return temps_[0]; }
1642 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric, "load-keyed-generic")
1643 DECLARE_HYDROGEN_ACCESSOR(LoadKeyedGeneric)
1647 class LLoadGlobalGeneric final : public LTemplateInstruction<1, 2, 1> {
1649 LLoadGlobalGeneric(LOperand* context, LOperand* global_object,
1651 inputs_[0] = context;
1652 inputs_[1] = global_object;
1656 LOperand* context() { return inputs_[0]; }
1657 LOperand* global_object() { return inputs_[1]; }
1658 LOperand* temp_vector() { return temps_[0]; }
1660 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric, "load-global-generic")
1661 DECLARE_HYDROGEN_ACCESSOR(LoadGlobalGeneric)
1663 Handle<Object> name() const { return hydrogen()->name(); }
1664 bool for_typeof() const { return hydrogen()->for_typeof(); }
1668 class LLoadContextSlot final : public LTemplateInstruction<1, 1, 0> {
1670 explicit LLoadContextSlot(LOperand* context) {
1671 inputs_[0] = context;
1674 LOperand* context() { return inputs_[0]; }
1676 DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot, "load-context-slot")
1677 DECLARE_HYDROGEN_ACCESSOR(LoadContextSlot)
1679 int slot_index() { return hydrogen()->slot_index(); }
1681 void PrintDataTo(StringStream* stream) override;
1685 class LStoreContextSlot final : public LTemplateInstruction<0, 2, 0> {
1687 LStoreContextSlot(LOperand* context, LOperand* value) {
1688 inputs_[0] = context;
1692 LOperand* context() { return inputs_[0]; }
1693 LOperand* value() { return inputs_[1]; }
1695 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot, "store-context-slot")
1696 DECLARE_HYDROGEN_ACCESSOR(StoreContextSlot)
1698 int slot_index() { return hydrogen()->slot_index(); }
1700 void PrintDataTo(StringStream* stream) override;
1704 class LPushArgument final : public LTemplateInstruction<0, 1, 0> {
1706 explicit LPushArgument(LOperand* value) {
1710 LOperand* value() { return inputs_[0]; }
1712 DECLARE_CONCRETE_INSTRUCTION(PushArgument, "push-argument")
1716 class LDrop final : public LTemplateInstruction<0, 0, 0> {
1718 explicit LDrop(int count) : count_(count) { }
1720 int count() const { return count_; }
1722 DECLARE_CONCRETE_INSTRUCTION(Drop, "drop")
1729 class LStoreCodeEntry final : public LTemplateInstruction<0, 2, 0> {
1731 LStoreCodeEntry(LOperand* function, LOperand* code_object) {
1732 inputs_[0] = function;
1733 inputs_[1] = code_object;
1736 LOperand* function() { return inputs_[0]; }
1737 LOperand* code_object() { return inputs_[1]; }
1739 void PrintDataTo(StringStream* stream) override;
1741 DECLARE_CONCRETE_INSTRUCTION(StoreCodeEntry, "store-code-entry")
1742 DECLARE_HYDROGEN_ACCESSOR(StoreCodeEntry)
1746 class LInnerAllocatedObject final : public LTemplateInstruction<1, 2, 0> {
1748 LInnerAllocatedObject(LOperand* base_object, LOperand* offset) {
1749 inputs_[0] = base_object;
1750 inputs_[1] = offset;
1753 LOperand* base_object() const { return inputs_[0]; }
1754 LOperand* offset() const { return inputs_[1]; }
1756 void PrintDataTo(StringStream* stream) override;
1758 DECLARE_CONCRETE_INSTRUCTION(InnerAllocatedObject, "inner-allocated-object")
1762 class LThisFunction final : public LTemplateInstruction<1, 0, 0> {
1764 DECLARE_CONCRETE_INSTRUCTION(ThisFunction, "this-function")
1765 DECLARE_HYDROGEN_ACCESSOR(ThisFunction)
1769 class LContext final : public LTemplateInstruction<1, 0, 0> {
1771 DECLARE_CONCRETE_INSTRUCTION(Context, "context")
1772 DECLARE_HYDROGEN_ACCESSOR(Context)
1776 class LDeclareGlobals final : public LTemplateInstruction<0, 1, 0> {
1778 explicit LDeclareGlobals(LOperand* context) {
1779 inputs_[0] = context;
1782 LOperand* context() { return inputs_[0]; }
1784 DECLARE_CONCRETE_INSTRUCTION(DeclareGlobals, "declare-globals")
1785 DECLARE_HYDROGEN_ACCESSOR(DeclareGlobals)
1789 class LCallJSFunction final : public LTemplateInstruction<1, 1, 0> {
1791 explicit LCallJSFunction(LOperand* function) {
1792 inputs_[0] = function;
1795 LOperand* function() { return inputs_[0]; }
1797 DECLARE_CONCRETE_INSTRUCTION(CallJSFunction, "call-js-function")
1798 DECLARE_HYDROGEN_ACCESSOR(CallJSFunction)
1800 void PrintDataTo(StringStream* stream) override;
1802 int arity() const { return hydrogen()->argument_count() - 1; }
1806 class LCallWithDescriptor final : public LTemplateResultInstruction<1> {
1808 LCallWithDescriptor(CallInterfaceDescriptor descriptor,
1809 const ZoneList<LOperand*>& operands, Zone* zone)
1810 : descriptor_(descriptor),
1811 inputs_(descriptor.GetRegisterParameterCount() + 1, zone) {
1812 DCHECK(descriptor.GetRegisterParameterCount() + 1 == operands.length());
1813 inputs_.AddAll(operands, zone);
1816 LOperand* target() const { return inputs_[0]; }
1818 const CallInterfaceDescriptor descriptor() { return descriptor_; }
1820 DECLARE_HYDROGEN_ACCESSOR(CallWithDescriptor)
1823 DECLARE_CONCRETE_INSTRUCTION(CallWithDescriptor, "call-with-descriptor")
1825 void PrintDataTo(StringStream* stream) override;
1827 int arity() const { return hydrogen()->argument_count() - 1; }
1829 CallInterfaceDescriptor descriptor_;
1830 ZoneList<LOperand*> inputs_;
1832 // Iterator support.
1833 int InputCount() final { return inputs_.length(); }
1834 LOperand* InputAt(int i) final { return inputs_[i]; }
1836 int TempCount() final { return 0; }
1837 LOperand* TempAt(int i) final { return NULL; }
1841 class LInvokeFunction final : public LTemplateInstruction<1, 2, 0> {
1843 LInvokeFunction(LOperand* context, LOperand* function) {
1844 inputs_[0] = context;
1845 inputs_[1] = function;
1848 LOperand* context() { return inputs_[0]; }
1849 LOperand* function() { return inputs_[1]; }
1851 DECLARE_CONCRETE_INSTRUCTION(InvokeFunction, "invoke-function")
1852 DECLARE_HYDROGEN_ACCESSOR(InvokeFunction)
1854 void PrintDataTo(StringStream* stream) override;
1856 int arity() const { return hydrogen()->argument_count() - 1; }
1860 class LCallFunction final : public LTemplateInstruction<1, 2, 2> {
1862 LCallFunction(LOperand* context, LOperand* function, LOperand* slot,
1864 inputs_[0] = context;
1865 inputs_[1] = function;
1870 LOperand* context() { return inputs_[0]; }
1871 LOperand* function() { return inputs_[1]; }
1872 LOperand* temp_slot() { return temps_[0]; }
1873 LOperand* temp_vector() { return temps_[1]; }
1875 DECLARE_CONCRETE_INSTRUCTION(CallFunction, "call-function")
1876 DECLARE_HYDROGEN_ACCESSOR(CallFunction)
1878 int arity() const { return hydrogen()->argument_count() - 1; }
1879 void PrintDataTo(StringStream* stream) override;
1883 class LCallNew final : public LTemplateInstruction<1, 2, 0> {
1885 LCallNew(LOperand* context, LOperand* constructor) {
1886 inputs_[0] = context;
1887 inputs_[1] = constructor;
1890 LOperand* context() { return inputs_[0]; }
1891 LOperand* constructor() { return inputs_[1]; }
1893 DECLARE_CONCRETE_INSTRUCTION(CallNew, "call-new")
1894 DECLARE_HYDROGEN_ACCESSOR(CallNew)
1896 void PrintDataTo(StringStream* stream) override;
1898 int arity() const { return hydrogen()->argument_count() - 1; }
1902 class LCallNewArray final : public LTemplateInstruction<1, 2, 0> {
1904 LCallNewArray(LOperand* context, LOperand* constructor) {
1905 inputs_[0] = context;
1906 inputs_[1] = constructor;
1909 LOperand* context() { return inputs_[0]; }
1910 LOperand* constructor() { return inputs_[1]; }
1912 DECLARE_CONCRETE_INSTRUCTION(CallNewArray, "call-new-array")
1913 DECLARE_HYDROGEN_ACCESSOR(CallNewArray)
1915 void PrintDataTo(StringStream* stream) override;
1917 int arity() const { return hydrogen()->argument_count() - 1; }
1921 class LCallRuntime final : public LTemplateInstruction<1, 1, 0> {
1923 explicit LCallRuntime(LOperand* context) {
1924 inputs_[0] = context;
1927 LOperand* context() { return inputs_[0]; }
1929 DECLARE_CONCRETE_INSTRUCTION(CallRuntime, "call-runtime")
1930 DECLARE_HYDROGEN_ACCESSOR(CallRuntime)
1932 bool ClobbersDoubleRegisters(Isolate* isolate) const override {
1933 return save_doubles() == kDontSaveFPRegs;
1936 const Runtime::Function* function() const { return hydrogen()->function(); }
1937 int arity() const { return hydrogen()->argument_count(); }
1938 SaveFPRegsMode save_doubles() const { return hydrogen()->save_doubles(); }
1942 class LInteger32ToDouble final : public LTemplateInstruction<1, 1, 0> {
1944 explicit LInteger32ToDouble(LOperand* value) {
1948 LOperand* value() { return inputs_[0]; }
1950 DECLARE_CONCRETE_INSTRUCTION(Integer32ToDouble, "int32-to-double")
1954 class LUint32ToDouble final : public LTemplateInstruction<1, 1, 0> {
1956 explicit LUint32ToDouble(LOperand* value) {
1960 LOperand* value() { return inputs_[0]; }
1962 DECLARE_CONCRETE_INSTRUCTION(Uint32ToDouble, "uint32-to-double")
1966 class LNumberTagU final : public LTemplateInstruction<1, 1, 2> {
1968 LNumberTagU(LOperand* value, LOperand* temp1, LOperand* temp2) {
1974 LOperand* value() { return inputs_[0]; }
1975 LOperand* temp1() { return temps_[0]; }
1976 LOperand* temp2() { return temps_[1]; }
1978 DECLARE_CONCRETE_INSTRUCTION(NumberTagU, "number-tag-u")
1982 class LNumberTagD final : public LTemplateInstruction<1, 1, 2> {
1984 LNumberTagD(LOperand* value, LOperand* temp, LOperand* temp2) {
1990 LOperand* value() { return inputs_[0]; }
1991 LOperand* temp() { return temps_[0]; }
1992 LOperand* temp2() { return temps_[1]; }
1994 DECLARE_CONCRETE_INSTRUCTION(NumberTagD, "number-tag-d")
1995 DECLARE_HYDROGEN_ACCESSOR(Change)
1999 class LDoubleToSmi final : public LTemplateInstruction<1, 1, 0> {
2001 explicit LDoubleToSmi(LOperand* value) {
2005 LOperand* value() { return inputs_[0]; }
2007 DECLARE_CONCRETE_INSTRUCTION(DoubleToSmi, "double-to-smi")
2008 DECLARE_HYDROGEN_ACCESSOR(UnaryOperation)
2010 bool truncating() { return hydrogen()->CanTruncateToInt32(); }
2014 // Sometimes truncating conversion from a tagged value to an int32.
2015 class LDoubleToI final : public LTemplateInstruction<1, 1, 0> {
2017 explicit LDoubleToI(LOperand* value) {
2021 LOperand* value() { return inputs_[0]; }
2023 DECLARE_CONCRETE_INSTRUCTION(DoubleToI, "double-to-i")
2024 DECLARE_HYDROGEN_ACCESSOR(UnaryOperation)
2026 bool truncating() { return hydrogen()->CanTruncateToInt32(); }
2030 // Truncating conversion from a tagged value to an int32.
2031 class LTaggedToI final : public LTemplateInstruction<1, 1, 2> {
2033 LTaggedToI(LOperand* value,
2041 LOperand* value() { return inputs_[0]; }
2042 LOperand* temp() { return temps_[0]; }
2043 LOperand* temp2() { return temps_[1]; }
2045 DECLARE_CONCRETE_INSTRUCTION(TaggedToI, "tagged-to-i")
2046 DECLARE_HYDROGEN_ACCESSOR(Change)
2048 bool truncating() { return hydrogen()->CanTruncateToInt32(); }
2052 class LSmiTag final : public LTemplateInstruction<1, 1, 0> {
2054 explicit LSmiTag(LOperand* value) {
2058 LOperand* value() { return inputs_[0]; }
2060 DECLARE_CONCRETE_INSTRUCTION(SmiTag, "smi-tag")
2061 DECLARE_HYDROGEN_ACCESSOR(Change)
2065 class LNumberUntagD final : public LTemplateInstruction<1, 1, 0> {
2067 explicit LNumberUntagD(LOperand* value) {
2071 LOperand* value() { return inputs_[0]; }
2073 DECLARE_CONCRETE_INSTRUCTION(NumberUntagD, "double-untag")
2074 DECLARE_HYDROGEN_ACCESSOR(Change)
2078 class LSmiUntag final : public LTemplateInstruction<1, 1, 0> {
2080 LSmiUntag(LOperand* value, bool needs_check)
2081 : needs_check_(needs_check) {
2085 LOperand* value() { return inputs_[0]; }
2086 bool needs_check() const { return needs_check_; }
2088 DECLARE_CONCRETE_INSTRUCTION(SmiUntag, "smi-untag")
2095 class LStoreNamedField final : public LTemplateInstruction<0, 2, 1> {
2097 LStoreNamedField(LOperand* object, LOperand* value, LOperand* temp) {
2098 inputs_[0] = object;
2103 LOperand* object() { return inputs_[0]; }
2104 LOperand* value() { return inputs_[1]; }
2105 LOperand* temp() { return temps_[0]; }
2107 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store-named-field")
2108 DECLARE_HYDROGEN_ACCESSOR(StoreNamedField)
2110 void PrintDataTo(StringStream* stream) override;
2112 Representation representation() const {
2113 return hydrogen()->field_representation();
2118 class LStoreNamedGeneric final : public LTemplateInstruction<0, 3, 0> {
2120 LStoreNamedGeneric(LOperand* context, LOperand* object, LOperand* value) {
2121 inputs_[0] = context;
2122 inputs_[1] = object;
2126 LOperand* context() { return inputs_[0]; }
2127 LOperand* object() { return inputs_[1]; }
2128 LOperand* value() { return inputs_[2]; }
2130 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric, "store-named-generic")
2131 DECLARE_HYDROGEN_ACCESSOR(StoreNamedGeneric)
2133 void PrintDataTo(StringStream* stream) override;
2135 Handle<Object> name() const { return hydrogen()->name(); }
2136 LanguageMode language_mode() { return hydrogen()->language_mode(); }
2140 class LStoreKeyed final : public LTemplateInstruction<0, 3, 0> {
2142 LStoreKeyed(LOperand* object, LOperand* key, LOperand* value) {
2143 inputs_[0] = object;
2148 bool is_external() const { return hydrogen()->is_external(); }
2149 bool is_fixed_typed_array() const {
2150 return hydrogen()->is_fixed_typed_array();
2152 bool is_typed_elements() const {
2153 return is_external() || is_fixed_typed_array();
2155 LOperand* elements() { return inputs_[0]; }
2156 LOperand* key() { return inputs_[1]; }
2157 LOperand* value() { return inputs_[2]; }
2158 ElementsKind elements_kind() const {
2159 return hydrogen()->elements_kind();
2162 DECLARE_CONCRETE_INSTRUCTION(StoreKeyed, "store-keyed")
2163 DECLARE_HYDROGEN_ACCESSOR(StoreKeyed)
2165 void PrintDataTo(StringStream* stream) override;
2166 bool NeedsCanonicalization() { return hydrogen()->NeedsCanonicalization(); }
2167 uint32_t base_offset() const { return hydrogen()->base_offset(); }
2171 class LStoreKeyedGeneric final : public LTemplateInstruction<0, 4, 0> {
2173 LStoreKeyedGeneric(LOperand* context,
2177 inputs_[0] = context;
2183 LOperand* context() { return inputs_[0]; }
2184 LOperand* object() { return inputs_[1]; }
2185 LOperand* key() { return inputs_[2]; }
2186 LOperand* value() { return inputs_[3]; }
2188 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric, "store-keyed-generic")
2189 DECLARE_HYDROGEN_ACCESSOR(StoreKeyedGeneric)
2191 void PrintDataTo(StringStream* stream) override;
2193 LanguageMode language_mode() { return hydrogen()->language_mode(); }
2197 class LTransitionElementsKind final : public LTemplateInstruction<0, 2, 1> {
2199 LTransitionElementsKind(LOperand* object,
2201 LOperand* new_map_temp) {
2202 inputs_[0] = object;
2203 inputs_[1] = context;
2204 temps_[0] = new_map_temp;
2207 LOperand* context() { return inputs_[1]; }
2208 LOperand* object() { return inputs_[0]; }
2209 LOperand* new_map_temp() { return temps_[0]; }
2211 DECLARE_CONCRETE_INSTRUCTION(TransitionElementsKind,
2212 "transition-elements-kind")
2213 DECLARE_HYDROGEN_ACCESSOR(TransitionElementsKind)
2215 void PrintDataTo(StringStream* stream) override;
2217 Handle<Map> original_map() { return hydrogen()->original_map().handle(); }
2218 Handle<Map> transitioned_map() {
2219 return hydrogen()->transitioned_map().handle();
2221 ElementsKind from_kind() { return hydrogen()->from_kind(); }
2222 ElementsKind to_kind() { return hydrogen()->to_kind(); }
2226 class LTrapAllocationMemento final : public LTemplateInstruction<0, 1, 1> {
2228 LTrapAllocationMemento(LOperand* object,
2230 inputs_[0] = object;
2234 LOperand* object() { return inputs_[0]; }
2235 LOperand* temp() { return temps_[0]; }
2237 DECLARE_CONCRETE_INSTRUCTION(TrapAllocationMemento,
2238 "trap-allocation-memento")
2242 class LMaybeGrowElements final : public LTemplateInstruction<1, 5, 0> {
2244 LMaybeGrowElements(LOperand* context, LOperand* object, LOperand* elements,
2245 LOperand* key, LOperand* current_capacity) {
2246 inputs_[0] = context;
2247 inputs_[1] = object;
2248 inputs_[2] = elements;
2250 inputs_[4] = current_capacity;
2253 LOperand* context() { return inputs_[0]; }
2254 LOperand* object() { return inputs_[1]; }
2255 LOperand* elements() { return inputs_[2]; }
2256 LOperand* key() { return inputs_[3]; }
2257 LOperand* current_capacity() { return inputs_[4]; }
2259 DECLARE_HYDROGEN_ACCESSOR(MaybeGrowElements)
2260 DECLARE_CONCRETE_INSTRUCTION(MaybeGrowElements, "maybe-grow-elements")
2264 class LStringAdd final : public LTemplateInstruction<1, 3, 0> {
2266 LStringAdd(LOperand* context, LOperand* left, LOperand* right) {
2267 inputs_[0] = context;
2272 LOperand* context() { return inputs_[0]; }
2273 LOperand* left() { return inputs_[1]; }
2274 LOperand* right() { return inputs_[2]; }
2276 DECLARE_CONCRETE_INSTRUCTION(StringAdd, "string-add")
2277 DECLARE_HYDROGEN_ACCESSOR(StringAdd)
2281 class LStringCharCodeAt final : public LTemplateInstruction<1, 3, 0> {
2283 LStringCharCodeAt(LOperand* context, LOperand* string, LOperand* index) {
2284 inputs_[0] = context;
2285 inputs_[1] = string;
2289 LOperand* context() { return inputs_[0]; }
2290 LOperand* string() { return inputs_[1]; }
2291 LOperand* index() { return inputs_[2]; }
2293 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt, "string-char-code-at")
2294 DECLARE_HYDROGEN_ACCESSOR(StringCharCodeAt)
2298 class LStringCharFromCode final : public LTemplateInstruction<1, 2, 0> {
2300 explicit LStringCharFromCode(LOperand* context, LOperand* char_code) {
2301 inputs_[0] = context;
2302 inputs_[1] = char_code;
2305 LOperand* context() { return inputs_[0]; }
2306 LOperand* char_code() { return inputs_[1]; }
2308 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode, "string-char-from-code")
2309 DECLARE_HYDROGEN_ACCESSOR(StringCharFromCode)
2313 class LCheckValue final : public LTemplateInstruction<0, 1, 0> {
2315 explicit LCheckValue(LOperand* value) {
2319 LOperand* value() { return inputs_[0]; }
2321 DECLARE_CONCRETE_INSTRUCTION(CheckValue, "check-value")
2322 DECLARE_HYDROGEN_ACCESSOR(CheckValue)
2326 class LCheckArrayBufferNotNeutered final
2327 : public LTemplateInstruction<0, 1, 0> {
2329 explicit LCheckArrayBufferNotNeutered(LOperand* view) { inputs_[0] = view; }
2331 LOperand* view() { return inputs_[0]; }
2333 DECLARE_CONCRETE_INSTRUCTION(CheckArrayBufferNotNeutered,
2334 "check-array-buffer-not-neutered")
2335 DECLARE_HYDROGEN_ACCESSOR(CheckArrayBufferNotNeutered)
2339 class LCheckInstanceType final : public LTemplateInstruction<0, 1, 0> {
2341 explicit LCheckInstanceType(LOperand* value) {
2345 LOperand* value() { return inputs_[0]; }
2347 DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType, "check-instance-type")
2348 DECLARE_HYDROGEN_ACCESSOR(CheckInstanceType)
2352 class LCheckMaps final : public LTemplateInstruction<0, 1, 0> {
2354 explicit LCheckMaps(LOperand* value = NULL) {
2358 LOperand* value() { return inputs_[0]; }
2360 DECLARE_CONCRETE_INSTRUCTION(CheckMaps, "check-maps")
2361 DECLARE_HYDROGEN_ACCESSOR(CheckMaps)
2365 class LCheckSmi final : public LTemplateInstruction<1, 1, 0> {
2367 explicit LCheckSmi(LOperand* value) {
2371 LOperand* value() { return inputs_[0]; }
2373 DECLARE_CONCRETE_INSTRUCTION(CheckSmi, "check-smi")
2377 class LCheckNonSmi final : public LTemplateInstruction<0, 1, 0> {
2379 explicit LCheckNonSmi(LOperand* value) {
2383 LOperand* value() { return inputs_[0]; }
2385 DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi, "check-non-smi")
2386 DECLARE_HYDROGEN_ACCESSOR(CheckHeapObject)
2390 class LClampDToUint8 final : public LTemplateInstruction<1, 1, 1> {
2392 LClampDToUint8(LOperand* unclamped, LOperand* temp) {
2393 inputs_[0] = unclamped;
2397 LOperand* unclamped() { return inputs_[0]; }
2398 LOperand* temp() { return temps_[0]; }
2400 DECLARE_CONCRETE_INSTRUCTION(ClampDToUint8, "clamp-d-to-uint8")
2404 class LClampIToUint8 final : public LTemplateInstruction<1, 1, 0> {
2406 explicit LClampIToUint8(LOperand* unclamped) {
2407 inputs_[0] = unclamped;
2410 LOperand* unclamped() { return inputs_[0]; }
2412 DECLARE_CONCRETE_INSTRUCTION(ClampIToUint8, "clamp-i-to-uint8")
2416 class LClampTToUint8 final : public LTemplateInstruction<1, 1, 1> {
2418 LClampTToUint8(LOperand* unclamped, LOperand* temp) {
2419 inputs_[0] = unclamped;
2423 LOperand* unclamped() { return inputs_[0]; }
2424 LOperand* temp() { return temps_[0]; }
2426 DECLARE_CONCRETE_INSTRUCTION(ClampTToUint8, "clamp-t-to-uint8")
2430 class LDoubleBits final : public LTemplateInstruction<1, 1, 0> {
2432 explicit LDoubleBits(LOperand* value) {
2436 LOperand* value() { return inputs_[0]; }
2438 DECLARE_CONCRETE_INSTRUCTION(DoubleBits, "double-bits")
2439 DECLARE_HYDROGEN_ACCESSOR(DoubleBits)
2443 class LConstructDouble final : public LTemplateInstruction<1, 2, 0> {
2445 LConstructDouble(LOperand* hi, LOperand* lo) {
2450 LOperand* hi() { return inputs_[0]; }
2451 LOperand* lo() { return inputs_[1]; }
2453 DECLARE_CONCRETE_INSTRUCTION(ConstructDouble, "construct-double")
2457 class LAllocate final : public LTemplateInstruction<1, 2, 2> {
2459 LAllocate(LOperand* context,
2463 inputs_[0] = context;
2469 LOperand* context() { return inputs_[0]; }
2470 LOperand* size() { return inputs_[1]; }
2471 LOperand* temp1() { return temps_[0]; }
2472 LOperand* temp2() { return temps_[1]; }
2474 DECLARE_CONCRETE_INSTRUCTION(Allocate, "allocate")
2475 DECLARE_HYDROGEN_ACCESSOR(Allocate)
2479 class LRegExpLiteral final : public LTemplateInstruction<1, 1, 0> {
2481 explicit LRegExpLiteral(LOperand* context) {
2482 inputs_[0] = context;
2485 LOperand* context() { return inputs_[0]; }
2487 DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral, "regexp-literal")
2488 DECLARE_HYDROGEN_ACCESSOR(RegExpLiteral)
2492 class LFunctionLiteral final : public LTemplateInstruction<1, 1, 0> {
2494 explicit LFunctionLiteral(LOperand* context) {
2495 inputs_[0] = context;
2498 LOperand* context() { return inputs_[0]; }
2500 DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral, "function-literal")
2501 DECLARE_HYDROGEN_ACCESSOR(FunctionLiteral)
2505 class LToFastProperties final : public LTemplateInstruction<1, 1, 0> {
2507 explicit LToFastProperties(LOperand* value) {
2511 LOperand* value() { return inputs_[0]; }
2513 DECLARE_CONCRETE_INSTRUCTION(ToFastProperties, "to-fast-properties")
2514 DECLARE_HYDROGEN_ACCESSOR(ToFastProperties)
2518 class LTypeof final : public LTemplateInstruction<1, 2, 0> {
2520 LTypeof(LOperand* context, LOperand* value) {
2521 inputs_[0] = context;
2525 LOperand* context() { return inputs_[0]; }
2526 LOperand* value() { return inputs_[1]; }
2528 DECLARE_CONCRETE_INSTRUCTION(Typeof, "typeof")
2532 class LTypeofIsAndBranch final : public LControlInstruction<1, 0> {
2534 explicit LTypeofIsAndBranch(LOperand* value) {
2538 LOperand* value() { return inputs_[0]; }
2540 DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch, "typeof-is-and-branch")
2541 DECLARE_HYDROGEN_ACCESSOR(TypeofIsAndBranch)
2543 Handle<String> type_literal() { return hydrogen()->type_literal(); }
2545 void PrintDataTo(StringStream* stream) override;
2549 class LIsConstructCallAndBranch final : public LControlInstruction<0, 1> {
2551 explicit LIsConstructCallAndBranch(LOperand* temp) {
2555 LOperand* temp() { return temps_[0]; }
2557 DECLARE_CONCRETE_INSTRUCTION(IsConstructCallAndBranch,
2558 "is-construct-call-and-branch")
2562 class LOsrEntry final : public LTemplateInstruction<0, 0, 0> {
2566 bool HasInterestingComment(LCodeGen* gen) const override { return false; }
2567 DECLARE_CONCRETE_INSTRUCTION(OsrEntry, "osr-entry")
2571 class LStackCheck final : public LTemplateInstruction<0, 1, 0> {
2573 explicit LStackCheck(LOperand* context) {
2574 inputs_[0] = context;
2577 LOperand* context() { return inputs_[0]; }
2579 DECLARE_CONCRETE_INSTRUCTION(StackCheck, "stack-check")
2580 DECLARE_HYDROGEN_ACCESSOR(StackCheck)
2582 Label* done_label() { return &done_label_; }
2589 class LForInPrepareMap final : public LTemplateInstruction<1, 2, 0> {
2591 LForInPrepareMap(LOperand* context, LOperand* object) {
2592 inputs_[0] = context;
2593 inputs_[1] = object;
2596 LOperand* context() { return inputs_[0]; }
2597 LOperand* object() { return inputs_[1]; }
2599 DECLARE_CONCRETE_INSTRUCTION(ForInPrepareMap, "for-in-prepare-map")
2603 class LForInCacheArray final : public LTemplateInstruction<1, 1, 0> {
2605 explicit LForInCacheArray(LOperand* map) {
2609 LOperand* map() { return inputs_[0]; }
2611 DECLARE_CONCRETE_INSTRUCTION(ForInCacheArray, "for-in-cache-array")
2614 return HForInCacheArray::cast(this->hydrogen_value())->idx();
2619 class LCheckMapValue final : public LTemplateInstruction<0, 2, 0> {
2621 LCheckMapValue(LOperand* value, LOperand* map) {
2626 LOperand* value() { return inputs_[0]; }
2627 LOperand* map() { return inputs_[1]; }
2629 DECLARE_CONCRETE_INSTRUCTION(CheckMapValue, "check-map-value")
2633 class LLoadFieldByIndex final : public LTemplateInstruction<1, 2, 0> {
2635 LLoadFieldByIndex(LOperand* object, LOperand* index) {
2636 inputs_[0] = object;
2640 LOperand* object() { return inputs_[0]; }
2641 LOperand* index() { return inputs_[1]; }
2643 DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex, "load-field-by-index")
2647 class LStoreFrameContext: public LTemplateInstruction<0, 1, 0> {
2649 explicit LStoreFrameContext(LOperand* context) {
2650 inputs_[0] = context;
2653 LOperand* context() { return inputs_[0]; }
2655 DECLARE_CONCRETE_INSTRUCTION(StoreFrameContext, "store-frame-context")
2659 class LAllocateBlockContext: public LTemplateInstruction<1, 2, 0> {
2661 LAllocateBlockContext(LOperand* context, LOperand* function) {
2662 inputs_[0] = context;
2663 inputs_[1] = function;
2666 LOperand* context() { return inputs_[0]; }
2667 LOperand* function() { return inputs_[1]; }
2669 Handle<ScopeInfo> scope_info() { return hydrogen()->scope_info(); }
2671 DECLARE_CONCRETE_INSTRUCTION(AllocateBlockContext, "allocate-block-context")
2672 DECLARE_HYDROGEN_ACCESSOR(AllocateBlockContext)
2676 class LChunkBuilder;
2677 class LPlatformChunk final : public LChunk {
2679 LPlatformChunk(CompilationInfo* info, HGraph* graph)
2680 : LChunk(info, graph) { }
2682 int GetNextSpillIndex(RegisterKind kind);
2683 LOperand* GetNextSpillSlot(RegisterKind kind);
2687 class LChunkBuilder final : public LChunkBuilderBase {
2689 LChunkBuilder(CompilationInfo* info, HGraph* graph, LAllocator* allocator)
2690 : LChunkBuilderBase(info, graph),
2691 current_instruction_(NULL),
2692 current_block_(NULL),
2694 allocator_(allocator) {}
2696 // Build the sequence for the graph.
2697 LPlatformChunk* Build();
2699 // Declare methods that deal with the individual node types.
2700 #define DECLARE_DO(type) LInstruction* Do##type(H##type* node);
2701 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_DO)
2704 LInstruction* DoMultiplyAdd(HMul* mul, HValue* addend);
2706 static bool HasMagicNumberForDivisor(int32_t divisor);
2708 LInstruction* DoMathFloor(HUnaryMathOperation* instr);
2709 LInstruction* DoMathRound(HUnaryMathOperation* instr);
2710 LInstruction* DoMathFround(HUnaryMathOperation* instr);
2711 LInstruction* DoMathAbs(HUnaryMathOperation* instr);
2712 LInstruction* DoMathLog(HUnaryMathOperation* instr);
2713 LInstruction* DoMathExp(HUnaryMathOperation* instr);
2714 LInstruction* DoMathSqrt(HUnaryMathOperation* instr);
2715 LInstruction* DoMathPowHalf(HUnaryMathOperation* instr);
2716 LInstruction* DoMathClz32(HUnaryMathOperation* instr);
2717 LInstruction* DoDivByPowerOf2I(HDiv* instr);
2718 LInstruction* DoDivByConstI(HDiv* instr);
2719 LInstruction* DoDivI(HDiv* instr);
2720 LInstruction* DoModByPowerOf2I(HMod* instr);
2721 LInstruction* DoModByConstI(HMod* instr);
2722 LInstruction* DoModI(HMod* instr);
2723 LInstruction* DoFlooringDivByPowerOf2I(HMathFloorOfDiv* instr);
2724 LInstruction* DoFlooringDivByConstI(HMathFloorOfDiv* instr);
2725 LInstruction* DoFlooringDivI(HMathFloorOfDiv* instr);
2728 // Methods for getting operands for Use / Define / Temp.
2729 LUnallocated* ToUnallocated(Register reg);
2730 LUnallocated* ToUnallocated(DoubleRegister reg);
2732 // Methods for setting up define-use relationships.
2733 MUST_USE_RESULT LOperand* Use(HValue* value, LUnallocated* operand);
2734 MUST_USE_RESULT LOperand* UseFixed(HValue* value, Register fixed_register);
2735 MUST_USE_RESULT LOperand* UseFixedDouble(HValue* value,
2736 DoubleRegister fixed_register);
2738 // A value that is guaranteed to be allocated to a register.
2739 // Operand created by UseRegister is guaranteed to be live until the end of
2740 // instruction. This means that register allocator will not reuse it's
2741 // register for any other operand inside instruction.
2742 // Operand created by UseRegisterAtStart is guaranteed to be live only at
2743 // instruction start. Register allocator is free to assign the same register
2744 // to some other operand used inside instruction (i.e. temporary or
2746 MUST_USE_RESULT LOperand* UseRegister(HValue* value);
2747 MUST_USE_RESULT LOperand* UseRegisterAtStart(HValue* value);
2749 // An input operand in a register that may be trashed.
2750 MUST_USE_RESULT LOperand* UseTempRegister(HValue* value);
2752 // An input operand in a register or stack slot.
2753 MUST_USE_RESULT LOperand* Use(HValue* value);
2754 MUST_USE_RESULT LOperand* UseAtStart(HValue* value);
2756 // An input operand in a register, stack slot or a constant operand.
2757 MUST_USE_RESULT LOperand* UseOrConstant(HValue* value);
2758 MUST_USE_RESULT LOperand* UseOrConstantAtStart(HValue* value);
2760 // An input operand in a register or a constant operand.
2761 MUST_USE_RESULT LOperand* UseRegisterOrConstant(HValue* value);
2762 MUST_USE_RESULT LOperand* UseRegisterOrConstantAtStart(HValue* value);
2764 // An input operand in a constant operand.
2765 MUST_USE_RESULT LOperand* UseConstant(HValue* value);
2767 // An input operand in register, stack slot or a constant operand.
2768 // Will not be moved to a register even if one is freely available.
2769 MUST_USE_RESULT LOperand* UseAny(HValue* value) override;
2771 // Temporary operand that must be in a register.
2772 MUST_USE_RESULT LUnallocated* TempRegister();
2773 MUST_USE_RESULT LUnallocated* TempDoubleRegister();
2774 MUST_USE_RESULT LOperand* FixedTemp(Register reg);
2775 MUST_USE_RESULT LOperand* FixedTemp(DoubleRegister reg);
2777 // Methods for setting up define-use relationships.
2778 // Return the same instruction that they are passed.
2779 LInstruction* Define(LTemplateResultInstruction<1>* instr,
2780 LUnallocated* result);
2781 LInstruction* DefineAsRegister(LTemplateResultInstruction<1>* instr);
2782 LInstruction* DefineAsSpilled(LTemplateResultInstruction<1>* instr,
2784 LInstruction* DefineSameAsFirst(LTemplateResultInstruction<1>* instr);
2785 LInstruction* DefineFixed(LTemplateResultInstruction<1>* instr,
2787 LInstruction* DefineFixedDouble(LTemplateResultInstruction<1>* instr,
2788 DoubleRegister reg);
2789 LInstruction* AssignEnvironment(LInstruction* instr);
2790 LInstruction* AssignPointerMap(LInstruction* instr);
2792 enum CanDeoptimize { CAN_DEOPTIMIZE_EAGERLY, CANNOT_DEOPTIMIZE_EAGERLY };
2794 // By default we assume that instruction sequences generated for calls
2795 // cannot deoptimize eagerly and we do not attach environment to this
2797 LInstruction* MarkAsCall(
2798 LInstruction* instr,
2799 HInstruction* hinstr,
2800 CanDeoptimize can_deoptimize = CANNOT_DEOPTIMIZE_EAGERLY);
2802 void VisitInstruction(HInstruction* current);
2803 void AddInstruction(LInstruction* instr, HInstruction* current);
2805 void DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block);
2806 LInstruction* DoBit(Token::Value op, HBitwiseBinaryOperation* instr);
2807 LInstruction* DoShift(Token::Value op, HBitwiseBinaryOperation* instr);
2808 LInstruction* DoArithmeticD(Token::Value op,
2809 HArithmeticBinaryOperation* instr);
2810 LInstruction* DoArithmeticT(Token::Value op,
2811 HBinaryOperation* instr);
2813 HInstruction* current_instruction_;
2814 HBasicBlock* current_block_;
2815 HBasicBlock* next_block_;
2816 LAllocator* allocator_;
2818 DISALLOW_COPY_AND_ASSIGN(LChunkBuilder);
2821 #undef DECLARE_HYDROGEN_ACCESSOR
2822 #undef DECLARE_CONCRETE_INSTRUCTION
2824 } } // namespace v8::internal
2826 #endif // V8_MIPS_LITHIUM_MIPS_H_