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