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