blob: 3f48e50e22d765c3f6a26d2f82ec798dd7752a1a [file] [log] [blame]
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001// Copyright 2010 the V8 project authors. All rights reserved.
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#ifndef V8_IA32_LITHIUM_IA32_H_
29#define V8_IA32_LITHIUM_IA32_H_
30
31#include "hydrogen.h"
32#include "lithium-allocator.h"
33#include "safepoint-table.h"
34
35namespace v8 {
36namespace internal {
37
38// Forward declarations.
39class LCodeGen;
40class LEnvironment;
41class Translation;
42class LGapNode;
43
44
45// Type hierarchy:
46//
47// LInstruction
48// LAccessArgumentsAt
49// LArgumentsElements
50// LArgumentsLength
51// LBinaryOperation
52// LAddI
53// LApplyArguments
54// LArithmeticD
55// LArithmeticT
56// LBitI
57// LBoundsCheck
58// LCmpID
59// LCmpIDAndBranch
60// LCmpJSObjectEq
61// LCmpJSObjectEqAndBranch
62// LCmpT
63// LDivI
64// LInstanceOf
65// LInstanceOfAndBranch
66// LLoadKeyedFastElement
67// LLoadKeyedGeneric
68// LModI
69// LMulI
ager@chromium.org5f0c45f2010-12-17 08:51:21 +000070// LPower
kasperl@chromium.orga5551262010-12-07 12:49:48 +000071// LShiftI
72// LSubI
73// LCallConstantFunction
74// LCallFunction
75// LCallGlobal
76// LCallKeyed
77// LCallKnownGlobal
78// LCallNamed
79// LCallRuntime
80// LCallStub
81// LConstant
82// LConstantD
83// LConstantI
84// LConstantT
85// LDeoptimize
86// LFunctionLiteral
87// LGlobalObject
88// LGlobalReceiver
89// LLabel
90// LLayzBailout
91// LLoadGlobal
92// LMaterializedLiteral
93// LArrayLiteral
94// LObjectLiteral
95// LRegExpLiteral
96// LOsrEntry
97// LParameter
98// LRegExpConstructResult
99// LStackCheck
100// LStoreKeyed
101// LStoreKeyedFastElement
102// LStoreKeyedGeneric
103// LStoreNamed
104// LStoreNamedField
105// LStoreNamedGeneric
106// LUnaryOperation
107// LArrayLength
108// LBitNotI
109// LBranch
110// LCallNew
111// LCheckFunction
112// LCheckInstanceType
113// LCheckMap
114// LCheckPrototypeMaps
115// LCheckSmi
116// LClassOfTest
117// LClassOfTestAndBranch
118// LDeleteProperty
119// LDoubleToI
120// LHasCachedArrayIndex
121// LHasCachedArrayIndexAndBranch
122// LHasInstanceType
123// LHasInstanceTypeAndBranch
124// LInteger32ToDouble
125// LIsNull
126// LIsNullAndBranch
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000127// LIsObject
128// LIsObjectAndBranch
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000129// LIsSmi
130// LIsSmiAndBranch
131// LLoadNamedField
132// LLoadNamedGeneric
133// LNumberTagD
134// LNumberTagI
135// LPushArgument
136// LReturn
137// LSmiTag
138// LStoreGlobal
139// LTaggedToI
140// LThrow
141// LTypeof
142// LTypeofIs
143// LTypeofIsAndBranch
144// LUnaryMathOperation
145// LValueOf
146// LUnknownOSRValue
147
148#define LITHIUM_ALL_INSTRUCTION_LIST(V) \
149 V(BinaryOperation) \
150 V(Constant) \
151 V(Call) \
152 V(MaterializedLiteral) \
153 V(StoreKeyed) \
154 V(StoreNamed) \
155 V(UnaryOperation) \
156 LITHIUM_CONCRETE_INSTRUCTION_LIST(V)
157
158
159#define LITHIUM_CONCRETE_INSTRUCTION_LIST(V) \
160 V(AccessArgumentsAt) \
161 V(AddI) \
162 V(ApplyArguments) \
163 V(ArgumentsElements) \
164 V(ArgumentsLength) \
165 V(ArithmeticD) \
166 V(ArithmeticT) \
167 V(ArrayLength) \
168 V(ArrayLiteral) \
169 V(BitI) \
170 V(BitNotI) \
171 V(BoundsCheck) \
172 V(Branch) \
173 V(CallConstantFunction) \
174 V(CallFunction) \
175 V(CallGlobal) \
176 V(CallKeyed) \
177 V(CallKnownGlobal) \
178 V(CallNamed) \
179 V(CallNew) \
180 V(CallRuntime) \
181 V(CallStub) \
182 V(CheckFunction) \
183 V(CheckInstanceType) \
184 V(CheckMap) \
185 V(CheckPrototypeMaps) \
186 V(CheckSmi) \
187 V(CmpID) \
188 V(CmpIDAndBranch) \
189 V(CmpJSObjectEq) \
190 V(CmpJSObjectEqAndBranch) \
191 V(CmpMapAndBranch) \
192 V(CmpT) \
193 V(CmpTAndBranch) \
194 V(ConstantD) \
195 V(ConstantI) \
196 V(ConstantT) \
197 V(DeleteProperty) \
198 V(Deoptimize) \
199 V(DivI) \
200 V(DoubleToI) \
201 V(FunctionLiteral) \
202 V(Gap) \
203 V(GlobalObject) \
204 V(GlobalReceiver) \
205 V(Goto) \
206 V(InstanceOf) \
207 V(InstanceOfAndBranch) \
208 V(Integer32ToDouble) \
209 V(IsNull) \
210 V(IsNullAndBranch) \
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000211 V(IsObject) \
212 V(IsObjectAndBranch) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000213 V(IsSmi) \
214 V(IsSmiAndBranch) \
215 V(HasInstanceType) \
216 V(HasInstanceTypeAndBranch) \
217 V(HasCachedArrayIndex) \
218 V(HasCachedArrayIndexAndBranch) \
219 V(ClassOfTest) \
220 V(ClassOfTestAndBranch) \
221 V(Label) \
222 V(LazyBailout) \
223 V(LoadElements) \
224 V(LoadGlobal) \
225 V(LoadKeyedFastElement) \
226 V(LoadKeyedGeneric) \
227 V(LoadNamedField) \
228 V(LoadNamedGeneric) \
229 V(ModI) \
230 V(MulI) \
231 V(NumberTagD) \
232 V(NumberTagI) \
233 V(NumberUntagD) \
234 V(ObjectLiteral) \
235 V(OsrEntry) \
236 V(Parameter) \
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000237 V(Power) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000238 V(PushArgument) \
239 V(RegExpLiteral) \
240 V(Return) \
241 V(ShiftI) \
242 V(SmiTag) \
243 V(SmiUntag) \
244 V(StackCheck) \
245 V(StoreGlobal) \
246 V(StoreKeyedFastElement) \
247 V(StoreKeyedGeneric) \
248 V(StoreNamedField) \
249 V(StoreNamedGeneric) \
250 V(SubI) \
251 V(TaggedToI) \
252 V(Throw) \
253 V(Typeof) \
254 V(TypeofIs) \
255 V(TypeofIsAndBranch) \
256 V(UnaryMathOperation) \
257 V(UnknownOSRValue) \
258 V(ValueOf)
259
260
261#define DECLARE_INSTRUCTION(type) \
262 virtual bool Is##type() const { return true; } \
263 static L##type* cast(LInstruction* instr) { \
264 ASSERT(instr->Is##type()); \
265 return reinterpret_cast<L##type*>(instr); \
266 }
267
268
269#define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic) \
270 virtual void CompileToNative(LCodeGen* generator); \
271 virtual const char* Mnemonic() const { return mnemonic; } \
272 DECLARE_INSTRUCTION(type)
273
274
275#define DECLARE_HYDROGEN_ACCESSOR(type) \
276 H##type* hydrogen() const { \
277 return H##type::cast(hydrogen_value()); \
278 }
279
280
281class LInstruction: public ZoneObject {
282 public:
283 LInstruction()
284 : hydrogen_value_(NULL) { }
285 virtual ~LInstruction() { }
286
287 virtual void CompileToNative(LCodeGen* generator) = 0;
288 virtual const char* Mnemonic() const = 0;
289 virtual void PrintTo(StringStream* stream) const;
290 virtual void PrintDataTo(StringStream* stream) const { }
291
292 // Declare virtual type testers.
293#define DECLARE_DO(type) virtual bool Is##type() const { return false; }
294 LITHIUM_ALL_INSTRUCTION_LIST(DECLARE_DO)
295#undef DECLARE_DO
296 virtual bool IsControl() const { return false; }
297
298 void set_environment(LEnvironment* env) { environment_.set(env); }
299 LEnvironment* environment() const { return environment_.get(); }
300 bool HasEnvironment() const { return environment_.is_set(); }
301
302 void set_pointer_map(LPointerMap* p) { pointer_map_.set(p); }
303 LPointerMap* pointer_map() const { return pointer_map_.get(); }
304 bool HasPointerMap() const { return pointer_map_.is_set(); }
305
306 void set_result(LOperand* operand) { result_.set(operand); }
307 LOperand* result() const { return result_.get(); }
308 bool HasResult() const { return result_.is_set(); }
309
310 void set_hydrogen_value(HValue* value) { hydrogen_value_ = value; }
311 HValue* hydrogen_value() const { return hydrogen_value_; }
312
313 void set_deoptimization_environment(LEnvironment* env) {
314 deoptimization_environment_.set(env);
315 }
316 LEnvironment* deoptimization_environment() const {
317 return deoptimization_environment_.get();
318 }
319 bool HasDeoptimizationEnvironment() const {
320 return deoptimization_environment_.is_set();
321 }
322
323 private:
324 SetOncePointer<LEnvironment> environment_;
325 SetOncePointer<LPointerMap> pointer_map_;
326 SetOncePointer<LOperand> result_;
327 HValue* hydrogen_value_;
328 SetOncePointer<LEnvironment> deoptimization_environment_;
329};
330
331
332class LGapResolver BASE_EMBEDDED {
333 public:
334 LGapResolver(const ZoneList<LMoveOperands>* moves, LOperand* marker_operand);
335 const ZoneList<LMoveOperands>* ResolveInReverseOrder();
336
337 private:
338 LGapNode* LookupNode(LOperand* operand);
339 bool CanReach(LGapNode* a, LGapNode* b, int visited_id);
340 bool CanReach(LGapNode* a, LGapNode* b);
341 void RegisterMove(LMoveOperands move);
342 void AddResultMove(LOperand* from, LOperand* to);
343 void AddResultMove(LGapNode* from, LGapNode* to);
344 void ResolveCycle(LGapNode* start);
345
346 ZoneList<LGapNode*> nodes_;
347 ZoneList<LGapNode*> identified_cycles_;
348 ZoneList<LMoveOperands> result_;
349 LOperand* marker_operand_;
350 int next_visited_id_;
351 int bailout_after_ast_id_;
352};
353
354
355class LParallelMove : public ZoneObject {
356 public:
357 LParallelMove() : move_operands_(4) { }
358
359 void AddMove(LOperand* from, LOperand* to) {
360 move_operands_.Add(LMoveOperands(from, to));
361 }
362
363 bool IsRedundant() const;
364
365 const ZoneList<LMoveOperands>* move_operands() const {
366 return &move_operands_;
367 }
368
369 void PrintDataTo(StringStream* stream) const;
370
371 private:
372 ZoneList<LMoveOperands> move_operands_;
373};
374
375
376class LGap: public LInstruction {
377 public:
378 explicit LGap(HBasicBlock* block)
379 : block_(block) {
380 parallel_moves_[BEFORE] = NULL;
381 parallel_moves_[START] = NULL;
382 parallel_moves_[END] = NULL;
383 parallel_moves_[AFTER] = NULL;
384 }
385
386 DECLARE_CONCRETE_INSTRUCTION(Gap, "gap")
387 virtual void PrintDataTo(StringStream* stream) const;
388
389 bool IsRedundant() const;
390
391 HBasicBlock* block() const { return block_; }
392
393 enum InnerPosition {
394 BEFORE,
395 START,
396 END,
397 AFTER,
398 FIRST_INNER_POSITION = BEFORE,
399 LAST_INNER_POSITION = AFTER
400 };
401
402 LParallelMove* GetOrCreateParallelMove(InnerPosition pos) {
403 if (parallel_moves_[pos] == NULL) parallel_moves_[pos] = new LParallelMove;
404 return parallel_moves_[pos];
405 }
406
407 LParallelMove* GetParallelMove(InnerPosition pos) {
408 return parallel_moves_[pos];
409 }
410
411 private:
412 LParallelMove* parallel_moves_[LAST_INNER_POSITION + 1];
413 HBasicBlock* block_;
414};
415
416
417class LGoto: public LInstruction {
418 public:
419 LGoto(int block_id, bool include_stack_check = false)
420 : block_id_(block_id), include_stack_check_(include_stack_check) { }
421
422 DECLARE_CONCRETE_INSTRUCTION(Goto, "goto")
423 virtual void PrintDataTo(StringStream* stream) const;
424 virtual bool IsControl() const { return true; }
425
426 int block_id() const { return block_id_; }
427 bool include_stack_check() const { return include_stack_check_; }
428
429 private:
430 int block_id_;
431 bool include_stack_check_;
432};
433
434
435class LLazyBailout: public LInstruction {
436 public:
437 LLazyBailout() : gap_instructions_size_(0) { }
438
439 DECLARE_CONCRETE_INSTRUCTION(LazyBailout, "lazy-bailout")
440
441 void set_gap_instructions_size(int gap_instructions_size) {
442 gap_instructions_size_ = gap_instructions_size;
443 }
444 int gap_instructions_size() { return gap_instructions_size_; }
445
446 private:
447 int gap_instructions_size_;
448};
449
450
451class LDeoptimize: public LInstruction {
452 public:
453 DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize")
454};
455
456
457class LLabel: public LGap {
458 public:
459 explicit LLabel(HBasicBlock* block)
460 : LGap(block), replacement_(NULL) { }
461
462 DECLARE_CONCRETE_INSTRUCTION(Label, "label")
463
464 virtual void PrintDataTo(StringStream* stream) const;
465
466 int block_id() const { return block()->block_id(); }
467 bool is_loop_header() const { return block()->IsLoopHeader(); }
468 Label* label() { return &label_; }
469 LLabel* replacement() const { return replacement_; }
470 void set_replacement(LLabel* label) { replacement_ = label; }
471 bool HasReplacement() const { return replacement_ != NULL; }
472
473 private:
474 Label label_;
475 LLabel* replacement_;
476};
477
478
479class LParameter: public LInstruction {
480 public:
481 DECLARE_CONCRETE_INSTRUCTION(Parameter, "parameter")
482};
483
484
485class LCallStub: public LInstruction {
486 public:
487 DECLARE_CONCRETE_INSTRUCTION(CallStub, "call-stub")
488 DECLARE_HYDROGEN_ACCESSOR(CallStub)
489
490 TranscendentalCache::Type transcendental_type() {
491 return hydrogen()->transcendental_type();
492 }
493};
494
495
496class LUnknownOSRValue: public LInstruction {
497 public:
498 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue, "unknown-osr-value")
499};
500
501
502class LUnaryOperation: public LInstruction {
503 public:
504 explicit LUnaryOperation(LOperand* input) : input_(input) { }
505
506 DECLARE_INSTRUCTION(UnaryOperation)
507
508 LOperand* input() const { return input_; }
509
510 virtual void PrintDataTo(StringStream* stream) const;
511
512 private:
513 LOperand* input_;
514};
515
516
517class LBinaryOperation: public LInstruction {
518 public:
519 LBinaryOperation(LOperand* left, LOperand* right)
520 : left_(left), right_(right) { }
521
522 DECLARE_INSTRUCTION(BinaryOperation)
523
524 LOperand* left() const { return left_; }
525 LOperand* right() const { return right_; }
526 virtual void PrintDataTo(StringStream* stream) const;
527
528 private:
529 LOperand* left_;
530 LOperand* right_;
531};
532
533
534class LApplyArguments: public LBinaryOperation {
535 public:
536 LApplyArguments(LOperand* function,
537 LOperand* receiver,
538 LOperand* length,
539 LOperand* elements)
540 : LBinaryOperation(function, receiver),
541 length_(length),
542 elements_(elements) { }
543
544 DECLARE_CONCRETE_INSTRUCTION(ApplyArguments, "apply-arguments")
545
546 LOperand* function() const { return left(); }
547 LOperand* receiver() const { return right(); }
548 LOperand* length() const { return length_; }
549 LOperand* elements() const { return elements_; }
550
551 private:
552 LOperand* length_;
553 LOperand* elements_;
554};
555
556
557class LAccessArgumentsAt: public LInstruction {
558 public:
559 LAccessArgumentsAt(LOperand* arguments, LOperand* length, LOperand* index)
560 : arguments_(arguments), length_(length), index_(index) { }
561
562 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt, "access-arguments-at")
563
564 LOperand* arguments() const { return arguments_; }
565 LOperand* length() const { return length_; }
566 LOperand* index() const { return index_; }
567
568 virtual void PrintDataTo(StringStream* stream) const;
569
570 private:
571 LOperand* arguments_;
572 LOperand* length_;
573 LOperand* index_;
574};
575
576
577class LArgumentsLength: public LUnaryOperation {
578 public:
579 explicit LArgumentsLength(LOperand* elements) : LUnaryOperation(elements) {}
580
581 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength, "arguments-length")
582};
583
584
585class LArgumentsElements: public LInstruction {
586 public:
587 LArgumentsElements() { }
588
589 DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements, "arguments-elements")
590};
591
592
593class LModI: public LBinaryOperation {
594 public:
595 LModI(LOperand* left, LOperand* right) : LBinaryOperation(left, right) { }
596
597 DECLARE_CONCRETE_INSTRUCTION(ModI, "mod-i")
598 DECLARE_HYDROGEN_ACCESSOR(Mod)
599};
600
601
602class LDivI: public LBinaryOperation {
603 public:
604 LDivI(LOperand* left, LOperand* right)
605 : LBinaryOperation(left, right) { }
606
607 DECLARE_CONCRETE_INSTRUCTION(DivI, "div-i")
608 DECLARE_HYDROGEN_ACCESSOR(Div)
609};
610
611
612class LMulI: public LBinaryOperation {
613 public:
614 LMulI(LOperand* left, LOperand* right, LOperand* temp)
615 : LBinaryOperation(left, right), temp_(temp) { }
616
617 DECLARE_CONCRETE_INSTRUCTION(MulI, "mul-i")
618 DECLARE_HYDROGEN_ACCESSOR(Mul)
619
620 LOperand* temp() const { return temp_; }
621
622 private:
623 LOperand* temp_;
624};
625
626
627class LCmpID: public LBinaryOperation {
628 public:
629 LCmpID(Token::Value op, LOperand* left, LOperand* right, bool is_double)
630 : LBinaryOperation(left, right), op_(op), is_double_(is_double) { }
631
632 Token::Value op() const { return op_; }
633 bool is_double() const { return is_double_; }
634
635 DECLARE_CONCRETE_INSTRUCTION(CmpID, "cmp-id")
636
637 private:
638 Token::Value op_;
639 bool is_double_;
640};
641
642
643class LCmpIDAndBranch: public LCmpID {
644 public:
645 LCmpIDAndBranch(Token::Value op,
646 LOperand* left,
647 LOperand* right,
648 int true_block_id,
649 int false_block_id,
650 bool is_double)
651 : LCmpID(op, left, right, is_double),
652 true_block_id_(true_block_id),
653 false_block_id_(false_block_id) { }
654
655 DECLARE_CONCRETE_INSTRUCTION(CmpIDAndBranch, "cmp-id-and-branch")
656 virtual void PrintDataTo(StringStream* stream) const;
657 virtual bool IsControl() const { return true; }
658
659 int true_block_id() const { return true_block_id_; }
660 int false_block_id() const { return false_block_id_; }
661
662 private:
663 int true_block_id_;
664 int false_block_id_;
665};
666
667
668class LUnaryMathOperation: public LUnaryOperation {
669 public:
670 explicit LUnaryMathOperation(LOperand* value)
671 : LUnaryOperation(value) { }
672
673 DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation, "unary-math-operation")
674 DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation)
675
676 virtual void PrintDataTo(StringStream* stream) const;
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000677 BuiltinFunctionId op() const { return hydrogen()->op(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000678};
679
680
681class LCmpJSObjectEq: public LBinaryOperation {
682 public:
683 LCmpJSObjectEq(LOperand* left, LOperand* right)
684 : LBinaryOperation(left, right) {}
685
686 DECLARE_CONCRETE_INSTRUCTION(CmpJSObjectEq, "cmp-jsobject-eq")
687};
688
689
690class LCmpJSObjectEqAndBranch: public LCmpJSObjectEq {
691 public:
692 LCmpJSObjectEqAndBranch(LOperand* left,
693 LOperand* right,
694 int true_block_id,
695 int false_block_id)
696 : LCmpJSObjectEq(left, right),
697 true_block_id_(true_block_id),
698 false_block_id_(false_block_id) { }
699
700 DECLARE_CONCRETE_INSTRUCTION(CmpJSObjectEqAndBranch,
701 "cmp-jsobject-eq-and-branch")
702
703 int true_block_id() const { return true_block_id_; }
704 int false_block_id() const { return false_block_id_; }
705
706 private:
707 int true_block_id_;
708 int false_block_id_;
709};
710
711
712class LIsNull: public LUnaryOperation {
713 public:
714 LIsNull(LOperand* value, bool is_strict)
715 : LUnaryOperation(value), is_strict_(is_strict) {}
716
717 DECLARE_CONCRETE_INSTRUCTION(IsNull, "is-null")
718
719 bool is_strict() const { return is_strict_; }
720
721 private:
722 bool is_strict_;
723};
724
725
726class LIsNullAndBranch: public LIsNull {
727 public:
728 LIsNullAndBranch(LOperand* value,
729 bool is_strict,
730 LOperand* temp,
731 int true_block_id,
732 int false_block_id)
733 : LIsNull(value, is_strict),
734 temp_(temp),
735 true_block_id_(true_block_id),
736 false_block_id_(false_block_id) { }
737
738 DECLARE_CONCRETE_INSTRUCTION(IsNullAndBranch, "is-null-and-branch")
739 virtual void PrintDataTo(StringStream* stream) const;
740 virtual bool IsControl() const { return true; }
741
742 int true_block_id() const { return true_block_id_; }
743 int false_block_id() const { return false_block_id_; }
744
745 LOperand* temp() const { return temp_; }
746
747 private:
748 LOperand* temp_;
749 int true_block_id_;
750 int false_block_id_;
751};
752
753
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000754class LIsObject: public LUnaryOperation {
755 public:
756 LIsObject(LOperand* value, LOperand* temp)
757 : LUnaryOperation(value), temp_(temp) {}
758
759 DECLARE_CONCRETE_INSTRUCTION(IsObject, "is-object")
760
761 LOperand* temp() const { return temp_; }
762
763 private:
764 LOperand* temp_;
765};
766
767
768class LIsObjectAndBranch: public LIsObject {
769 public:
770 LIsObjectAndBranch(LOperand* value,
771 LOperand* temp,
772 LOperand* temp2,
773 int true_block_id,
774 int false_block_id)
775 : LIsObject(value, temp),
776 temp2_(temp2),
777 true_block_id_(true_block_id),
778 false_block_id_(false_block_id) { }
779
780 DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch, "is-object-and-branch")
781 virtual void PrintDataTo(StringStream* stream) const;
782 virtual bool IsControl() const { return true; }
783
784 int true_block_id() const { return true_block_id_; }
785 int false_block_id() const { return false_block_id_; }
786
787 LOperand* temp2() const { return temp2_; }
788
789 private:
790 LOperand* temp2_;
791 int true_block_id_;
792 int false_block_id_;
793};
794
795
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000796class LIsSmi: public LUnaryOperation {
797 public:
798 explicit LIsSmi(LOperand* value) : LUnaryOperation(value) {}
799
800 DECLARE_CONCRETE_INSTRUCTION(IsSmi, "is-smi")
801 DECLARE_HYDROGEN_ACCESSOR(IsSmi)
802};
803
804
805class LIsSmiAndBranch: public LIsSmi {
806 public:
807 LIsSmiAndBranch(LOperand* value,
808 int true_block_id,
809 int false_block_id)
810 : LIsSmi(value),
811 true_block_id_(true_block_id),
812 false_block_id_(false_block_id) { }
813
814 DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch, "is-smi-and-branch")
815 virtual void PrintDataTo(StringStream* stream) const;
816 virtual bool IsControl() const { return true; }
817
818 int true_block_id() const { return true_block_id_; }
819 int false_block_id() const { return false_block_id_; }
820
821 private:
822 int true_block_id_;
823 int false_block_id_;
824};
825
826
827class LHasInstanceType: public LUnaryOperation {
828 public:
829 explicit LHasInstanceType(LOperand* value)
830 : LUnaryOperation(value) { }
831
832 DECLARE_CONCRETE_INSTRUCTION(HasInstanceType, "has-instance-type")
833 DECLARE_HYDROGEN_ACCESSOR(HasInstanceType)
834
835 InstanceType TestType(); // The type to test against when generating code.
836 Condition BranchCondition(); // The branch condition for 'true'.
837};
838
839
840class LHasInstanceTypeAndBranch: public LHasInstanceType {
841 public:
842 LHasInstanceTypeAndBranch(LOperand* value,
843 LOperand* temporary,
844 int true_block_id,
845 int false_block_id)
846 : LHasInstanceType(value),
847 temp_(temporary),
848 true_block_id_(true_block_id),
849 false_block_id_(false_block_id) { }
850
851 DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch,
852 "has-instance-type-and-branch")
853 virtual void PrintDataTo(StringStream* stream) const;
854 virtual bool IsControl() const { return true; }
855
856 int true_block_id() const { return true_block_id_; }
857 int false_block_id() const { return false_block_id_; }
858
859 LOperand* temp() { return temp_; }
860
861 private:
862 LOperand* temp_;
863 int true_block_id_;
864 int false_block_id_;
865};
866
867
868class LHasCachedArrayIndex: public LUnaryOperation {
869 public:
870 explicit LHasCachedArrayIndex(LOperand* value) : LUnaryOperation(value) {}
871
872 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndex, "has-cached-array-index")
873 DECLARE_HYDROGEN_ACCESSOR(HasCachedArrayIndex)
874};
875
876
877class LHasCachedArrayIndexAndBranch: public LHasCachedArrayIndex {
878 public:
879 LHasCachedArrayIndexAndBranch(LOperand* value,
880 int true_block_id,
881 int false_block_id)
882 : LHasCachedArrayIndex(value),
883 true_block_id_(true_block_id),
884 false_block_id_(false_block_id) { }
885
886 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndexAndBranch,
887 "has-cached-array-index-and-branch")
888 virtual void PrintDataTo(StringStream* stream) const;
889 virtual bool IsControl() const { return true; }
890
891 int true_block_id() const { return true_block_id_; }
892 int false_block_id() const { return false_block_id_; }
893
894 private:
895 int true_block_id_;
896 int false_block_id_;
897};
898
899
900class LClassOfTest: public LUnaryOperation {
901 public:
902 LClassOfTest(LOperand* value, LOperand* temp)
903 : LUnaryOperation(value), temporary_(temp) {}
904
905 DECLARE_CONCRETE_INSTRUCTION(ClassOfTest, "class-of-test")
906 DECLARE_HYDROGEN_ACCESSOR(ClassOfTest)
907
908 virtual void PrintDataTo(StringStream* stream) const;
909
910 LOperand* temporary() { return temporary_; }
911
912 private:
913 LOperand *temporary_;
914};
915
916
917class LClassOfTestAndBranch: public LClassOfTest {
918 public:
919 LClassOfTestAndBranch(LOperand* value,
920 LOperand* temporary,
921 LOperand* temporary2,
922 int true_block_id,
923 int false_block_id)
924 : LClassOfTest(value, temporary),
925 temporary2_(temporary2),
926 true_block_id_(true_block_id),
927 false_block_id_(false_block_id) { }
928
929 DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch,
930 "class-of-test-and-branch")
931 virtual void PrintDataTo(StringStream* stream) const;
932 virtual bool IsControl() const { return true; }
933
934 int true_block_id() const { return true_block_id_; }
935 int false_block_id() const { return false_block_id_; }
936 LOperand* temporary2() { return temporary2_; }
937
938 private:
939 LOperand* temporary2_;
940 int true_block_id_;
941 int false_block_id_;
942};
943
944
945class LCmpT: public LBinaryOperation {
946 public:
947 LCmpT(LOperand* left, LOperand* right) : LBinaryOperation(left, right) {}
948
949 DECLARE_CONCRETE_INSTRUCTION(CmpT, "cmp-t")
950 DECLARE_HYDROGEN_ACCESSOR(Compare)
951
952 Token::Value op() const { return hydrogen()->token(); }
953};
954
955
956class LCmpTAndBranch: public LCmpT {
957 public:
958 LCmpTAndBranch(LOperand* left,
959 LOperand* right,
960 int true_block_id,
961 int false_block_id)
962 : LCmpT(left, right),
963 true_block_id_(true_block_id),
964 false_block_id_(false_block_id) { }
965
966 DECLARE_CONCRETE_INSTRUCTION(CmpTAndBranch, "cmp-t-and-branch")
967
968 int true_block_id() const { return true_block_id_; }
969 int false_block_id() const { return false_block_id_; }
970
971 private:
972 int true_block_id_;
973 int false_block_id_;
974};
975
976
977class LInstanceOf: public LBinaryOperation {
978 public:
979 LInstanceOf(LOperand* left, LOperand* right)
980 : LBinaryOperation(left, right) { }
981
982 DECLARE_CONCRETE_INSTRUCTION(InstanceOf, "instance-of")
983};
984
985
986class LInstanceOfAndBranch: public LInstanceOf {
987 public:
988 LInstanceOfAndBranch(LOperand* left,
989 LOperand* right,
990 int true_block_id,
991 int false_block_id)
992 : LInstanceOf(left, right),
993 true_block_id_(true_block_id),
994 false_block_id_(false_block_id) { }
995
996 DECLARE_CONCRETE_INSTRUCTION(InstanceOfAndBranch, "instance-of-and-branch")
997
998 int true_block_id() const { return true_block_id_; }
999 int false_block_id() const { return false_block_id_; }
1000
1001 private:
1002 int true_block_id_;
1003 int false_block_id_;
1004};
1005
1006
1007class LBoundsCheck: public LBinaryOperation {
1008 public:
1009 LBoundsCheck(LOperand* index, LOperand* length)
1010 : LBinaryOperation(index, length) { }
1011
1012 LOperand* index() const { return left(); }
1013 LOperand* length() const { return right(); }
1014
1015 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck, "bounds-check")
1016};
1017
1018
1019class LBitI: public LBinaryOperation {
1020 public:
1021 LBitI(Token::Value op, LOperand* left, LOperand* right)
1022 : LBinaryOperation(left, right), op_(op) { }
1023
1024 Token::Value op() const { return op_; }
1025
1026 DECLARE_CONCRETE_INSTRUCTION(BitI, "bit-i")
1027
1028 private:
1029 Token::Value op_;
1030};
1031
1032
1033class LShiftI: public LBinaryOperation {
1034 public:
1035 LShiftI(Token::Value op, LOperand* left, LOperand* right, bool can_deopt)
1036 : LBinaryOperation(left, right), op_(op), can_deopt_(can_deopt) { }
1037
1038 Token::Value op() const { return op_; }
1039
1040 bool can_deopt() const { return can_deopt_; }
1041
1042 DECLARE_CONCRETE_INSTRUCTION(ShiftI, "shift-i")
1043
1044 private:
1045 Token::Value op_;
1046 bool can_deopt_;
1047};
1048
1049
1050class LSubI: public LBinaryOperation {
1051 public:
1052 LSubI(LOperand* left, LOperand* right)
1053 : LBinaryOperation(left, right) { }
1054
1055 DECLARE_CONCRETE_INSTRUCTION(SubI, "sub-i")
1056 DECLARE_HYDROGEN_ACCESSOR(Sub)
1057};
1058
1059
1060class LConstant: public LInstruction {
1061 DECLARE_INSTRUCTION(Constant)
1062};
1063
1064
1065class LConstantI: public LConstant {
1066 public:
1067 explicit LConstantI(int32_t value) : value_(value) { }
1068 int32_t value() const { return value_; }
1069
1070 DECLARE_CONCRETE_INSTRUCTION(ConstantI, "constant-i")
1071
1072 private:
1073 int32_t value_;
1074};
1075
1076
1077class LConstantD: public LConstant {
1078 public:
1079 explicit LConstantD(double value) : value_(value) { }
1080 double value() const { return value_; }
1081
1082 DECLARE_CONCRETE_INSTRUCTION(ConstantD, "constant-d")
1083
1084 private:
1085 double value_;
1086};
1087
1088
1089class LConstantT: public LConstant {
1090 public:
1091 explicit LConstantT(Handle<Object> value) : value_(value) { }
1092 Handle<Object> value() const { return value_; }
1093
1094 DECLARE_CONCRETE_INSTRUCTION(ConstantT, "constant-t")
1095
1096 private:
1097 Handle<Object> value_;
1098};
1099
1100
1101class LBranch: public LUnaryOperation {
1102 public:
1103 LBranch(LOperand* input, int true_block_id, int false_block_id)
1104 : LUnaryOperation(input),
1105 true_block_id_(true_block_id),
1106 false_block_id_(false_block_id) { }
1107
1108 DECLARE_CONCRETE_INSTRUCTION(Branch, "branch")
1109 DECLARE_HYDROGEN_ACCESSOR(Value)
1110
1111 virtual void PrintDataTo(StringStream* stream) const;
1112 virtual bool IsControl() const { return true; }
1113
1114 int true_block_id() const { return true_block_id_; }
1115 int false_block_id() const { return false_block_id_; }
1116
1117 private:
1118 int true_block_id_;
1119 int false_block_id_;
1120};
1121
1122
1123class LCmpMapAndBranch: public LUnaryOperation {
1124 public:
1125 LCmpMapAndBranch(LOperand* value,
1126 Handle<Map> map,
1127 int true_block_id,
1128 int false_block_id)
1129 : LUnaryOperation(value),
1130 map_(map),
1131 true_block_id_(true_block_id),
1132 false_block_id_(false_block_id) { }
1133
1134 DECLARE_CONCRETE_INSTRUCTION(CmpMapAndBranch, "cmp-map-and-branch")
1135
1136 virtual bool IsControl() const { return true; }
1137
1138 Handle<Map> map() const { return map_; }
1139 int true_block_id() const { return true_block_id_; }
1140 int false_block_id() const { return false_block_id_; }
1141
1142 private:
1143 Handle<Map> map_;
1144 int true_block_id_;
1145 int false_block_id_;
1146};
1147
1148
1149class LArrayLength: public LUnaryOperation {
1150 public:
1151 LArrayLength(LOperand* input, LOperand* temporary)
1152 : LUnaryOperation(input), temporary_(temporary) { }
1153
1154 LOperand* temporary() const { return temporary_; }
1155
1156 DECLARE_CONCRETE_INSTRUCTION(ArrayLength, "array-length")
1157 DECLARE_HYDROGEN_ACCESSOR(ArrayLength)
1158
1159 private:
1160 LOperand* temporary_;
1161};
1162
1163
1164class LValueOf: public LUnaryOperation {
1165 public:
1166 LValueOf(LOperand* input, LOperand* temporary)
1167 : LUnaryOperation(input), temporary_(temporary) { }
1168
1169 LOperand* temporary() const { return temporary_; }
1170
1171 DECLARE_CONCRETE_INSTRUCTION(ValueOf, "value-of")
1172 DECLARE_HYDROGEN_ACCESSOR(ValueOf)
1173
1174 private:
1175 LOperand* temporary_;
1176};
1177
1178
1179class LThrow: public LUnaryOperation {
1180 public:
1181 explicit LThrow(LOperand* value) : LUnaryOperation(value) { }
1182
1183 DECLARE_CONCRETE_INSTRUCTION(Throw, "throw")
1184};
1185
1186
1187class LBitNotI: public LUnaryOperation {
1188 public:
1189 explicit LBitNotI(LOperand* use) : LUnaryOperation(use) { }
1190
1191 DECLARE_CONCRETE_INSTRUCTION(BitNotI, "bit-not-i")
1192};
1193
1194
1195class LAddI: public LBinaryOperation {
1196 public:
1197 LAddI(LOperand* left, LOperand* right)
1198 : LBinaryOperation(left, right) { }
1199
1200 DECLARE_CONCRETE_INSTRUCTION(AddI, "add-i")
1201 DECLARE_HYDROGEN_ACCESSOR(Add)
1202};
1203
1204
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001205class LPower: public LBinaryOperation {
1206 public:
1207 LPower(LOperand* left, LOperand* right)
1208 : LBinaryOperation(left, right) { }
1209
1210 DECLARE_CONCRETE_INSTRUCTION(Power, "power")
1211 DECLARE_HYDROGEN_ACCESSOR(Power)
1212};
1213
1214
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001215class LArithmeticD: public LBinaryOperation {
1216 public:
1217 LArithmeticD(Token::Value op, LOperand* left, LOperand* right)
1218 : LBinaryOperation(left, right), op_(op) { }
1219
1220 Token::Value op() const { return op_; }
1221
1222 virtual void CompileToNative(LCodeGen* generator);
1223 virtual const char* Mnemonic() const;
1224
1225 private:
1226 Token::Value op_;
1227};
1228
1229
1230class LArithmeticT: public LBinaryOperation {
1231 public:
1232 LArithmeticT(Token::Value op, LOperand* left, LOperand* right)
1233 : LBinaryOperation(left, right), op_(op) { }
1234
1235 virtual void CompileToNative(LCodeGen* generator);
1236 virtual const char* Mnemonic() const;
1237
1238 Token::Value op() const { return op_; }
1239
1240 private:
1241 Token::Value op_;
1242};
1243
1244
1245class LReturn: public LUnaryOperation {
1246 public:
1247 explicit LReturn(LOperand* use) : LUnaryOperation(use) { }
1248
1249 DECLARE_CONCRETE_INSTRUCTION(Return, "return")
1250};
1251
1252
1253class LLoadNamedField: public LUnaryOperation {
1254 public:
1255 explicit LLoadNamedField(LOperand* object) : LUnaryOperation(object) { }
1256
1257 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load-named-field")
1258 DECLARE_HYDROGEN_ACCESSOR(LoadNamedField)
1259};
1260
1261
1262class LLoadNamedGeneric: public LUnaryOperation {
1263 public:
1264 explicit LLoadNamedGeneric(LOperand* object) : LUnaryOperation(object) { }
1265
1266 DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric, "load-named-generic")
1267 DECLARE_HYDROGEN_ACCESSOR(LoadNamedGeneric)
1268
1269 LOperand* object() const { return input(); }
1270 Handle<Object> name() const { return hydrogen()->name(); }
1271};
1272
1273
1274class LLoadElements: public LUnaryOperation {
1275 public:
1276 explicit LLoadElements(LOperand* obj) : LUnaryOperation(obj) { }
1277
1278 DECLARE_CONCRETE_INSTRUCTION(LoadElements, "load-elements")
1279};
1280
1281
1282class LLoadKeyedFastElement: public LBinaryOperation {
1283 public:
1284 LLoadKeyedFastElement(LOperand* elements,
1285 LOperand* key,
1286 LOperand* load_result)
1287 : LBinaryOperation(elements, key),
1288 load_result_(load_result) { }
1289
1290 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement, "load-keyed-fast-element")
1291 DECLARE_HYDROGEN_ACCESSOR(LoadKeyedFastElement)
1292
1293 LOperand* elements() const { return left(); }
1294 LOperand* key() const { return right(); }
1295 LOperand* load_result() const { return load_result_; }
1296
1297 private:
1298 LOperand* load_result_;
1299};
1300
1301
1302class LLoadKeyedGeneric: public LBinaryOperation {
1303 public:
1304 LLoadKeyedGeneric(LOperand* obj, LOperand* key)
1305 : LBinaryOperation(obj, key) { }
1306
1307 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric, "load-keyed-generic")
1308
1309 LOperand* object() const { return left(); }
1310 LOperand* key() const { return right(); }
1311};
1312
1313
1314class LLoadGlobal: public LInstruction {
1315 public:
1316 DECLARE_CONCRETE_INSTRUCTION(LoadGlobal, "load-global")
1317 DECLARE_HYDROGEN_ACCESSOR(LoadGlobal)
1318};
1319
1320
1321class LStoreGlobal: public LUnaryOperation {
1322 public:
1323 explicit LStoreGlobal(LOperand* value) : LUnaryOperation(value) {}
1324
1325 DECLARE_CONCRETE_INSTRUCTION(StoreGlobal, "store-global")
1326 DECLARE_HYDROGEN_ACCESSOR(StoreGlobal)
1327};
1328
1329
1330class LPushArgument: public LUnaryOperation {
1331 public:
1332 explicit LPushArgument(LOperand* argument) : LUnaryOperation(argument) {}
1333
1334 DECLARE_CONCRETE_INSTRUCTION(PushArgument, "push-argument")
1335};
1336
1337
1338class LGlobalObject: public LInstruction {
1339 public:
1340 DECLARE_CONCRETE_INSTRUCTION(GlobalObject, "global-object")
1341};
1342
1343
1344class LGlobalReceiver: public LInstruction {
1345 public:
1346 DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver, "global-receiver")
1347};
1348
1349
1350class LCallConstantFunction: public LInstruction {
1351 public:
1352 DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction, "call-constant-function")
1353 DECLARE_HYDROGEN_ACCESSOR(CallConstantFunction)
1354
1355 virtual void PrintDataTo(StringStream* stream) const;
1356
1357 Handle<JSFunction> function() const { return hydrogen()->function(); }
1358 int arity() const { return hydrogen()->argument_count() - 1; }
1359};
1360
1361
1362class LCallKeyed: public LInstruction {
1363 public:
1364 DECLARE_CONCRETE_INSTRUCTION(CallKeyed, "call-keyed")
1365 DECLARE_HYDROGEN_ACCESSOR(CallKeyed)
1366
1367 virtual void PrintDataTo(StringStream* stream) const;
1368
1369 int arity() const { return hydrogen()->argument_count() - 1; }
1370};
1371
1372
1373class LCallNamed: public LInstruction {
1374 public:
1375 DECLARE_CONCRETE_INSTRUCTION(CallNamed, "call-named")
1376 DECLARE_HYDROGEN_ACCESSOR(CallNamed)
1377
1378 virtual void PrintDataTo(StringStream* stream) const;
1379
1380 Handle<String> name() const { return hydrogen()->name(); }
1381 int arity() const { return hydrogen()->argument_count() - 1; }
1382};
1383
1384
1385class LCallFunction: public LInstruction {
1386 public:
1387 DECLARE_CONCRETE_INSTRUCTION(CallFunction, "call-function")
1388 DECLARE_HYDROGEN_ACCESSOR(CallFunction)
1389
1390 int arity() const { return hydrogen()->argument_count() - 2; }
1391};
1392
1393
1394class LCallGlobal: public LInstruction {
1395 public:
1396 DECLARE_CONCRETE_INSTRUCTION(CallGlobal, "call-global")
1397 DECLARE_HYDROGEN_ACCESSOR(CallGlobal)
1398
1399 virtual void PrintDataTo(StringStream* stream) const;
1400
1401 Handle<String> name() const {return hydrogen()->name(); }
1402 int arity() const { return hydrogen()->argument_count() - 1; }
1403};
1404
1405
1406class LCallKnownGlobal: public LInstruction {
1407 public:
1408 DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal, "call-known-global")
1409 DECLARE_HYDROGEN_ACCESSOR(CallKnownGlobal)
1410
1411 virtual void PrintDataTo(StringStream* stream) const;
1412
1413 Handle<JSFunction> target() const { return hydrogen()->target(); }
1414 int arity() const { return hydrogen()->argument_count() - 1; }
1415};
1416
1417
1418class LCallNew: public LUnaryOperation {
1419 public:
1420 explicit LCallNew(LOperand* constructor) : LUnaryOperation(constructor) { }
1421
1422 DECLARE_CONCRETE_INSTRUCTION(CallNew, "call-new")
1423 DECLARE_HYDROGEN_ACCESSOR(CallNew)
1424
1425 virtual void PrintDataTo(StringStream* stream) const;
1426
1427 int arity() const { return hydrogen()->argument_count() - 1; }
1428};
1429
1430
1431class LCallRuntime: public LInstruction {
1432 public:
1433 DECLARE_CONCRETE_INSTRUCTION(CallRuntime, "call-runtime")
1434 DECLARE_HYDROGEN_ACCESSOR(CallRuntime)
1435
1436 Runtime::Function* function() const { return hydrogen()->function(); }
1437 int arity() const { return hydrogen()->argument_count(); }
1438};
1439
1440
1441class LInteger32ToDouble: public LUnaryOperation {
1442 public:
1443 explicit LInteger32ToDouble(LOperand* use) : LUnaryOperation(use) { }
1444
1445 DECLARE_CONCRETE_INSTRUCTION(Integer32ToDouble, "int32-to-double")
1446};
1447
1448
1449class LNumberTagI: public LUnaryOperation {
1450 public:
1451 explicit LNumberTagI(LOperand* use) : LUnaryOperation(use) { }
1452
1453 DECLARE_CONCRETE_INSTRUCTION(NumberTagI, "number-tag-i")
1454};
1455
1456
1457class LNumberTagD: public LUnaryOperation {
1458 public:
1459 explicit LNumberTagD(LOperand* value, LOperand* temp)
1460 : LUnaryOperation(value), temp_(temp) { }
1461
1462 DECLARE_CONCRETE_INSTRUCTION(NumberTagD, "number-tag-d")
1463
1464 LOperand* temp() const { return temp_; }
1465
1466 private:
1467 LOperand* temp_;
1468};
1469
1470
1471// Sometimes truncating conversion from a tagged value to an int32.
1472class LDoubleToI: public LUnaryOperation {
1473 public:
1474 explicit LDoubleToI(LOperand* value) : LUnaryOperation(value) { }
1475
1476 DECLARE_CONCRETE_INSTRUCTION(DoubleToI, "double-to-i")
1477 DECLARE_HYDROGEN_ACCESSOR(Change)
1478
1479 bool truncating() { return hydrogen()->CanTruncateToInt32(); }
1480};
1481
1482
1483// Truncating conversion from a tagged value to an int32.
1484class LTaggedToI: public LUnaryOperation {
1485 public:
1486 LTaggedToI(LOperand* value, LOperand* temp)
1487 : LUnaryOperation(value), temp_(temp) { }
1488
1489 DECLARE_CONCRETE_INSTRUCTION(TaggedToI, "tagged-to-i")
1490 DECLARE_HYDROGEN_ACCESSOR(Change)
1491
1492 bool truncating() { return hydrogen()->CanTruncateToInt32(); }
1493 LOperand* temp() const { return temp_; }
1494
1495 private:
1496 LOperand* temp_;
1497};
1498
1499
1500class LSmiTag: public LUnaryOperation {
1501 public:
1502 explicit LSmiTag(LOperand* use) : LUnaryOperation(use) { }
1503
1504 DECLARE_CONCRETE_INSTRUCTION(SmiTag, "smi-tag")
1505};
1506
1507
1508class LNumberUntagD: public LUnaryOperation {
1509 public:
1510 explicit LNumberUntagD(LOperand* value) : LUnaryOperation(value) { }
1511
1512 DECLARE_CONCRETE_INSTRUCTION(NumberUntagD, "double-untag")
1513};
1514
1515
1516class LSmiUntag: public LUnaryOperation {
1517 public:
1518 LSmiUntag(LOperand* use, bool needs_check)
1519 : LUnaryOperation(use), needs_check_(needs_check) { }
1520
1521 DECLARE_CONCRETE_INSTRUCTION(SmiUntag, "smi-untag")
1522
1523 bool needs_check() const { return needs_check_; }
1524
1525 private:
1526 bool needs_check_;
1527};
1528
1529
1530class LStoreNamed: public LInstruction {
1531 public:
1532 LStoreNamed(LOperand* obj, Handle<Object> name, LOperand* val)
1533 : object_(obj), name_(name), value_(val) { }
1534
1535 DECLARE_INSTRUCTION(StoreNamed)
1536
1537 virtual void PrintDataTo(StringStream* stream) const;
1538
1539 LOperand* object() const { return object_; }
1540 Handle<Object> name() const { return name_; }
1541 LOperand* value() const { return value_; }
1542
1543 private:
1544 LOperand* object_;
1545 Handle<Object> name_;
1546 LOperand* value_;
1547};
1548
1549
1550class LStoreNamedField: public LStoreNamed {
1551 public:
1552 LStoreNamedField(LOperand* obj,
1553 Handle<Object> name,
1554 LOperand* val,
1555 bool in_object,
1556 int offset,
1557 LOperand* temp,
1558 bool needs_write_barrier,
1559 Handle<Map> transition)
1560 : LStoreNamed(obj, name, val),
1561 is_in_object_(in_object),
1562 offset_(offset),
1563 temp_(temp),
1564 needs_write_barrier_(needs_write_barrier),
1565 transition_(transition) { }
1566
1567 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store-named-field")
1568
1569 bool is_in_object() { return is_in_object_; }
1570 int offset() { return offset_; }
1571 LOperand* temp() { return temp_; }
1572 bool needs_write_barrier() { return needs_write_barrier_; }
1573 Handle<Map> transition() const { return transition_; }
1574 void set_transition(Handle<Map> map) { transition_ = map; }
1575
1576 private:
1577 bool is_in_object_;
1578 int offset_;
1579 LOperand* temp_;
1580 bool needs_write_barrier_;
1581 Handle<Map> transition_;
1582};
1583
1584
1585class LStoreNamedGeneric: public LStoreNamed {
1586 public:
1587 LStoreNamedGeneric(LOperand* obj,
1588 Handle<Object> name,
1589 LOperand* val)
1590 : LStoreNamed(obj, name, val) { }
1591
1592 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric, "store-named-generic")
1593};
1594
1595
1596class LStoreKeyed: public LInstruction {
1597 public:
1598 LStoreKeyed(LOperand* obj, LOperand* key, LOperand* val)
1599 : object_(obj), key_(key), value_(val) { }
1600
1601 DECLARE_INSTRUCTION(StoreKeyed)
1602
1603 virtual void PrintDataTo(StringStream* stream) const;
1604
1605 LOperand* object() const { return object_; }
1606 LOperand* key() const { return key_; }
1607 LOperand* value() const { return value_; }
1608
1609 private:
1610 LOperand* object_;
1611 LOperand* key_;
1612 LOperand* value_;
1613};
1614
1615
1616class LStoreKeyedFastElement: public LStoreKeyed {
1617 public:
1618 LStoreKeyedFastElement(LOperand* obj, LOperand* key, LOperand* val)
1619 : LStoreKeyed(obj, key, val) {}
1620
1621 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement,
1622 "store-keyed-fast-element")
1623 DECLARE_HYDROGEN_ACCESSOR(StoreKeyedFastElement)
1624};
1625
1626
1627class LStoreKeyedGeneric: public LStoreKeyed {
1628 public:
1629 LStoreKeyedGeneric(LOperand* obj, LOperand* key, LOperand* val)
1630 : LStoreKeyed(obj, key, val) { }
1631
1632 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric, "store-keyed-generic")
1633};
1634
1635
1636class LCheckFunction: public LUnaryOperation {
1637 public:
1638 explicit LCheckFunction(LOperand* use) : LUnaryOperation(use) { }
1639
1640 DECLARE_CONCRETE_INSTRUCTION(CheckFunction, "check-function")
1641 DECLARE_HYDROGEN_ACCESSOR(CheckFunction)
1642};
1643
1644
1645class LCheckInstanceType: public LUnaryOperation {
1646 public:
1647 LCheckInstanceType(LOperand* use, LOperand* temp)
1648 : LUnaryOperation(use), temp_(temp) { }
1649
1650 DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType, "check-instance-type")
1651 DECLARE_HYDROGEN_ACCESSOR(CheckInstanceType)
1652
1653 LOperand* temp() const { return temp_; }
1654
1655 private:
1656 LOperand* temp_;
1657};
1658
1659
1660class LCheckMap: public LUnaryOperation {
1661 public:
1662 explicit LCheckMap(LOperand* use) : LUnaryOperation(use) { }
1663
1664 DECLARE_CONCRETE_INSTRUCTION(CheckMap, "check-map")
1665 DECLARE_HYDROGEN_ACCESSOR(CheckMap)
1666};
1667
1668
1669class LCheckPrototypeMaps: public LInstruction {
1670 public:
1671 LCheckPrototypeMaps(LOperand* temp,
1672 Handle<JSObject> holder,
1673 Handle<Map> receiver_map)
1674 : temp_(temp),
1675 holder_(holder),
1676 receiver_map_(receiver_map) { }
1677
1678 DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps, "check-prototype-maps")
1679
1680 LOperand* temp() const { return temp_; }
1681 Handle<JSObject> holder() const { return holder_; }
1682 Handle<Map> receiver_map() const { return receiver_map_; }
1683
1684 private:
1685 LOperand* temp_;
1686 Handle<JSObject> holder_;
1687 Handle<Map> receiver_map_;
1688};
1689
1690
1691class LCheckSmi: public LUnaryOperation {
1692 public:
1693 LCheckSmi(LOperand* use, Condition condition)
1694 : LUnaryOperation(use), condition_(condition) { }
1695
1696 Condition condition() const { return condition_; }
1697
1698 virtual void CompileToNative(LCodeGen* generator);
1699 virtual const char* Mnemonic() const {
1700 return (condition_ == zero) ? "check-non-smi" : "check-smi";
1701 }
1702
1703 private:
1704 Condition condition_;
1705};
1706
1707
1708class LMaterializedLiteral: public LInstruction {
1709 public:
1710 DECLARE_INSTRUCTION(MaterializedLiteral)
1711};
1712
1713
1714class LArrayLiteral: public LMaterializedLiteral {
1715 public:
1716 DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral, "array-literal")
1717 DECLARE_HYDROGEN_ACCESSOR(ArrayLiteral)
1718};
1719
1720
1721class LObjectLiteral: public LMaterializedLiteral {
1722 public:
1723 DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral, "object-literal")
1724 DECLARE_HYDROGEN_ACCESSOR(ObjectLiteral)
1725};
1726
1727
1728class LRegExpLiteral: public LMaterializedLiteral {
1729 public:
1730 DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral, "regexp-literal")
1731 DECLARE_HYDROGEN_ACCESSOR(RegExpLiteral)
1732};
1733
1734
1735class LFunctionLiteral: public LInstruction {
1736 public:
1737 DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral, "function-literal")
1738 DECLARE_HYDROGEN_ACCESSOR(FunctionLiteral)
1739
1740 Handle<SharedFunctionInfo> shared_info() { return hydrogen()->shared_info(); }
1741};
1742
1743
1744class LTypeof: public LUnaryOperation {
1745 public:
1746 explicit LTypeof(LOperand* input) : LUnaryOperation(input) { }
1747
1748 DECLARE_CONCRETE_INSTRUCTION(Typeof, "typeof")
1749};
1750
1751
1752class LTypeofIs: public LUnaryOperation {
1753 public:
1754 explicit LTypeofIs(LOperand* input) : LUnaryOperation(input) { }
1755 virtual void PrintDataTo(StringStream* stream) const;
1756
1757 DECLARE_CONCRETE_INSTRUCTION(TypeofIs, "typeof-is")
1758 DECLARE_HYDROGEN_ACCESSOR(TypeofIs)
1759
1760 Handle<String> type_literal() { return hydrogen()->type_literal(); }
1761};
1762
1763
1764class LTypeofIsAndBranch: public LTypeofIs {
1765 public:
1766 LTypeofIsAndBranch(LOperand* value,
1767 int true_block_id,
1768 int false_block_id)
1769 : LTypeofIs(value),
1770 true_block_id_(true_block_id),
1771 false_block_id_(false_block_id) { }
1772
1773 DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch, "typeof-is-and-branch")
1774
1775 virtual void PrintDataTo(StringStream* stream) const;
1776 virtual bool IsControl() const { return true; }
1777
1778 int true_block_id() const { return true_block_id_; }
1779 int false_block_id() const { return false_block_id_; }
1780
1781 private:
1782 int true_block_id_;
1783 int false_block_id_;
1784};
1785
1786
1787class LDeleteProperty: public LBinaryOperation {
1788 public:
1789 LDeleteProperty(LOperand* obj, LOperand* key) : LBinaryOperation(obj, key) {}
1790
1791 DECLARE_CONCRETE_INSTRUCTION(DeleteProperty, "delete-property")
1792
1793 LOperand* object() const { return left(); }
1794 LOperand* key() const { return right(); }
1795};
1796
1797
1798class LOsrEntry: public LInstruction {
1799 public:
1800 LOsrEntry();
1801
1802 DECLARE_CONCRETE_INSTRUCTION(OsrEntry, "osr-entry")
1803
1804 LOperand** SpilledRegisterArray() { return register_spills_; }
1805 LOperand** SpilledDoubleRegisterArray() { return double_register_spills_; }
1806
1807 void MarkSpilledRegister(int allocation_index, LOperand* spill_operand);
1808 void MarkSpilledDoubleRegister(int allocation_index,
1809 LOperand* spill_operand);
1810
1811 private:
1812 // Arrays of spill slot operands for registers with an assigned spill
1813 // slot, i.e., that must also be restored to the spill slot on OSR entry.
1814 // NULL if the register has no assigned spill slot. Indexed by allocation
1815 // index.
1816 LOperand* register_spills_[Register::kNumAllocatableRegisters];
1817 LOperand* double_register_spills_[DoubleRegister::kNumAllocatableRegisters];
1818};
1819
1820
1821class LStackCheck: public LInstruction {
1822 public:
1823 DECLARE_CONCRETE_INSTRUCTION(StackCheck, "stack-check")
1824};
1825
1826
1827class LPointerMap: public ZoneObject {
1828 public:
1829 explicit LPointerMap(int position)
1830 : pointer_operands_(8), position_(position), lithium_position_(-1) { }
1831
1832 const ZoneList<LOperand*>* operands() const { return &pointer_operands_; }
1833 int position() const { return position_; }
1834 int lithium_position() const { return lithium_position_; }
1835
1836 void set_lithium_position(int pos) {
1837 ASSERT(lithium_position_ == -1);
1838 lithium_position_ = pos;
1839 }
1840
1841 void RecordPointer(LOperand* op);
1842 void PrintTo(StringStream* stream) const;
1843
1844 private:
1845 ZoneList<LOperand*> pointer_operands_;
1846 int position_;
1847 int lithium_position_;
1848};
1849
1850
1851class LEnvironment: public ZoneObject {
1852 public:
1853 LEnvironment(Handle<JSFunction> closure,
1854 int ast_id,
1855 int parameter_count,
1856 int argument_count,
1857 int value_count,
1858 LEnvironment* outer)
1859 : closure_(closure),
1860 arguments_stack_height_(argument_count),
1861 deoptimization_index_(Safepoint::kNoDeoptimizationIndex),
1862 translation_index_(-1),
1863 ast_id_(ast_id),
1864 parameter_count_(parameter_count),
1865 values_(value_count),
1866 representations_(value_count),
1867 spilled_registers_(NULL),
1868 spilled_double_registers_(NULL),
1869 outer_(outer) {
1870 }
1871
1872 Handle<JSFunction> closure() const { return closure_; }
1873 int arguments_stack_height() const { return arguments_stack_height_; }
1874 int deoptimization_index() const { return deoptimization_index_; }
1875 int translation_index() const { return translation_index_; }
1876 int ast_id() const { return ast_id_; }
1877 int parameter_count() const { return parameter_count_; }
1878 const ZoneList<LOperand*>* values() const { return &values_; }
1879 LEnvironment* outer() const { return outer_; }
1880
1881 void AddValue(LOperand* operand, Representation representation) {
1882 values_.Add(operand);
1883 representations_.Add(representation);
1884 }
1885
1886 bool HasTaggedValueAt(int index) const {
1887 return representations_[index].IsTagged();
1888 }
1889
1890 void Register(int deoptimization_index, int translation_index) {
1891 ASSERT(!HasBeenRegistered());
1892 deoptimization_index_ = deoptimization_index;
1893 translation_index_ = translation_index;
1894 }
1895 bool HasBeenRegistered() const {
1896 return deoptimization_index_ != Safepoint::kNoDeoptimizationIndex;
1897 }
1898
1899 void SetSpilledRegisters(LOperand** registers,
1900 LOperand** double_registers) {
1901 spilled_registers_ = registers;
1902 spilled_double_registers_ = double_registers;
1903 }
1904
1905 // Emit frame translation commands for this environment.
1906 void WriteTranslation(LCodeGen* cgen, Translation* translation) const;
1907
1908 void PrintTo(StringStream* stream) const;
1909
1910 private:
1911 Handle<JSFunction> closure_;
1912 int arguments_stack_height_;
1913 int deoptimization_index_;
1914 int translation_index_;
1915 int ast_id_;
1916 int parameter_count_;
1917 ZoneList<LOperand*> values_;
1918 ZoneList<Representation> representations_;
1919
1920 // Allocation index indexed arrays of spill slot operands for registers
1921 // that are also in spill slots at an OSR entry. NULL for environments
1922 // that do not correspond to an OSR entry.
1923 LOperand** spilled_registers_;
1924 LOperand** spilled_double_registers_;
1925
1926 LEnvironment* outer_;
1927};
1928
1929class LChunkBuilder;
1930class LChunk: public ZoneObject {
1931 public:
1932 explicit LChunk(HGraph* graph);
1933
1934 int AddInstruction(LInstruction* instruction, HBasicBlock* block);
1935 LConstantOperand* DefineConstantOperand(HConstant* constant);
1936 Handle<Object> LookupLiteral(LConstantOperand* operand) const;
1937 Representation LookupLiteralRepresentation(LConstantOperand* operand) const;
1938
1939 int GetNextSpillIndex(bool is_double);
1940 LOperand* GetNextSpillSlot(bool is_double);
1941
1942 int ParameterAt(int index);
1943 int GetParameterStackSlot(int index) const;
1944 int spill_slot_count() const { return spill_slot_count_; }
1945 HGraph* graph() const { return graph_; }
1946 const ZoneList<LInstruction*>* instructions() const { return &instructions_; }
1947 void AddGapMove(int index, LOperand* from, LOperand* to);
1948 LGap* GetGapAt(int index) const;
1949 bool IsGapAt(int index) const;
1950 int NearestGapPos(int index) const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001951 void MarkEmptyBlocks();
1952 const ZoneList<LPointerMap*>* pointer_maps() const { return &pointer_maps_; }
1953 LLabel* GetLabel(int block_id) const {
1954 HBasicBlock* block = graph_->blocks()->at(block_id);
1955 int first_instruction = block->first_instruction_index();
1956 return LLabel::cast(instructions_[first_instruction]);
1957 }
1958 int LookupDestination(int block_id) const {
1959 LLabel* cur = GetLabel(block_id);
1960 while (cur->replacement() != NULL) {
1961 cur = cur->replacement();
1962 }
1963 return cur->block_id();
1964 }
1965 Label* GetAssemblyLabel(int block_id) const {
1966 LLabel* label = GetLabel(block_id);
1967 ASSERT(!label->HasReplacement());
1968 return label->label();
1969 }
1970
1971 const ZoneList<Handle<JSFunction> >* inlined_closures() const {
1972 return &inlined_closures_;
1973 }
1974
1975 void AddInlinedClosure(Handle<JSFunction> closure) {
1976 inlined_closures_.Add(closure);
1977 }
1978
1979 void Verify() const;
1980
1981 private:
1982 int spill_slot_count_;
1983 HGraph* const graph_;
1984 ZoneList<LInstruction*> instructions_;
1985 ZoneList<LPointerMap*> pointer_maps_;
1986 ZoneList<Handle<JSFunction> > inlined_closures_;
1987};
1988
1989
1990class LChunkBuilder BASE_EMBEDDED {
1991 public:
1992 LChunkBuilder(HGraph* graph, LAllocator* allocator)
1993 : chunk_(NULL),
1994 graph_(graph),
1995 status_(UNUSED),
1996 current_instruction_(NULL),
1997 current_block_(NULL),
1998 next_block_(NULL),
1999 argument_count_(0),
2000 allocator_(allocator),
2001 position_(RelocInfo::kNoPosition),
2002 instructions_pending_deoptimization_environment_(NULL),
2003 pending_deoptimization_ast_id_(AstNode::kNoNumber) { }
2004
2005 // Build the sequence for the graph.
2006 LChunk* Build();
2007
2008 // Declare methods that deal with the individual node types.
2009#define DECLARE_DO(type) LInstruction* Do##type(H##type* node);
2010 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_DO)
2011#undef DECLARE_DO
2012
2013 private:
2014 enum Status {
2015 UNUSED,
2016 BUILDING,
2017 DONE,
2018 ABORTED
2019 };
2020
2021 LChunk* chunk() const { return chunk_; }
2022 HGraph* graph() const { return graph_; }
2023
2024 bool is_unused() const { return status_ == UNUSED; }
2025 bool is_building() const { return status_ == BUILDING; }
2026 bool is_done() const { return status_ == DONE; }
2027 bool is_aborted() const { return status_ == ABORTED; }
2028
2029 void Abort(const char* format, ...);
2030
2031 // Methods for getting operands for Use / Define / Temp.
2032 LRegister* ToOperand(Register reg);
2033 LUnallocated* ToUnallocated(Register reg);
2034 LUnallocated* ToUnallocated(XMMRegister reg);
2035
2036 // Methods for setting up define-use relationships.
2037 LOperand* Use(HValue* value, LUnallocated* operand);
2038 LOperand* UseFixed(HValue* value, Register fixed_register);
2039 LOperand* UseFixedDouble(HValue* value, XMMRegister fixed_register);
2040
2041 // A value that is guaranteed to be allocated to a register.
2042 // Operand created by UseRegister is guaranteed to be live until the end of
2043 // instruction. This means that register allocator will not reuse it's
2044 // register for any other operand inside instruction.
2045 // Operand created by UseRegisterAtStart is guaranteed to be live only at
2046 // instruction start. Register allocator is free to assign the same register
2047 // to some other operand used inside instruction (i.e. temporary or
2048 // output).
2049 LOperand* UseRegister(HValue* value);
2050 LOperand* UseRegisterAtStart(HValue* value);
2051
2052 // A value in a register that may be trashed.
2053 LOperand* UseTempRegister(HValue* value);
2054 LOperand* Use(HValue* value);
2055 LOperand* UseAtStart(HValue* value);
2056 LOperand* UseOrConstant(HValue* value);
2057 LOperand* UseOrConstantAtStart(HValue* value);
2058 LOperand* UseRegisterOrConstant(HValue* value);
2059 LOperand* UseRegisterOrConstantAtStart(HValue* value);
2060
2061 // Methods for setting up define-use relationships.
2062 // Return the same instruction that they are passed.
2063 LInstruction* Define(LInstruction* instr, LUnallocated* result);
2064 LInstruction* Define(LInstruction* instr);
2065 LInstruction* DefineAsRegister(LInstruction* instr);
2066 LInstruction* DefineAsSpilled(LInstruction* instr, int index);
2067 LInstruction* DefineSameAsAny(LInstruction* instr);
2068 LInstruction* DefineSameAsFirst(LInstruction* instr);
2069 LInstruction* DefineFixed(LInstruction* instr, Register reg);
2070 LInstruction* DefineFixedDouble(LInstruction* instr, XMMRegister reg);
2071 LInstruction* AssignEnvironment(LInstruction* instr);
2072 LInstruction* AssignPointerMap(LInstruction* instr);
2073
2074 enum CanDeoptimize { CAN_DEOPTIMIZE_EAGERLY, CANNOT_DEOPTIMIZE_EAGERLY };
2075
2076 // By default we assume that instruction sequences generated for calls
2077 // cannot deoptimize eagerly and we do not attach environment to this
2078 // instruction.
2079 LInstruction* MarkAsCall(
2080 LInstruction* instr,
2081 HInstruction* hinstr,
2082 CanDeoptimize can_deoptimize = CANNOT_DEOPTIMIZE_EAGERLY);
2083
2084 LInstruction* SetInstructionPendingDeoptimizationEnvironment(
2085 LInstruction* instr, int ast_id);
2086 void ClearInstructionPendingDeoptimizationEnvironment();
2087
2088 LEnvironment* CreateEnvironment(HEnvironment* hydrogen_env);
2089
2090 // Temporary operand that may be a memory location.
2091 LOperand* Temp();
2092 // Temporary operand that must be in a register.
2093 LUnallocated* TempRegister();
2094 LOperand* FixedTemp(Register reg);
2095 LOperand* FixedTemp(XMMRegister reg);
2096
2097 void VisitInstruction(HInstruction* current);
2098
2099 void DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block);
2100 LInstruction* DoBit(Token::Value op, HBitwiseBinaryOperation* instr);
2101 LInstruction* DoShift(Token::Value op, HBitwiseBinaryOperation* instr);
2102 LInstruction* DoArithmeticD(Token::Value op,
2103 HArithmeticBinaryOperation* instr);
2104 LInstruction* DoArithmeticT(Token::Value op,
2105 HArithmeticBinaryOperation* instr);
2106
2107 LChunk* chunk_;
2108 HGraph* const graph_;
2109 Status status_;
2110 HInstruction* current_instruction_;
2111 HBasicBlock* current_block_;
2112 HBasicBlock* next_block_;
2113 int argument_count_;
2114 LAllocator* allocator_;
2115 int position_;
2116 LInstruction* instructions_pending_deoptimization_environment_;
2117 int pending_deoptimization_ast_id_;
2118
2119 DISALLOW_COPY_AND_ASSIGN(LChunkBuilder);
2120};
2121
2122#undef DECLARE_HYDROGEN_ACCESSOR
2123#undef DECLARE_INSTRUCTION
2124#undef DECLARE_CONCRETE_INSTRUCTION
2125
2126} } // namespace v8::internal
2127
2128#endif // V8_IA32_LITHIUM_IA32_H_