blob: 07f0a8d90bdcf78994cb7ffa268aebd3b0757387 [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;
kasperl@chromium.orga5551262010-12-07 12:49:48 +000041
42
43// Type hierarchy:
44//
45// LInstruction
46// LAccessArgumentsAt
47// LArgumentsElements
48// LArgumentsLength
49// LBinaryOperation
50// LAddI
51// LApplyArguments
52// LArithmeticD
53// LArithmeticT
54// LBitI
55// LBoundsCheck
56// LCmpID
57// LCmpIDAndBranch
58// LCmpJSObjectEq
59// LCmpJSObjectEqAndBranch
60// LCmpT
61// LDivI
62// LInstanceOf
63// LInstanceOfAndBranch
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +000064// LInstanceOfKnownGlobal
kasperl@chromium.orga5551262010-12-07 12:49:48 +000065// LLoadKeyedFastElement
66// LLoadKeyedGeneric
67// LModI
68// LMulI
ager@chromium.org5f0c45f2010-12-17 08:51:21 +000069// LPower
kasperl@chromium.orga5551262010-12-07 12:49:48 +000070// LShiftI
71// LSubI
72// LCallConstantFunction
73// LCallFunction
74// LCallGlobal
75// LCallKeyed
76// LCallKnownGlobal
77// LCallNamed
78// LCallRuntime
79// LCallStub
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +000080// LCheckPrototypeMaps
kasperl@chromium.orga5551262010-12-07 12:49:48 +000081// LConstant
82// LConstantD
83// LConstantI
84// LConstantT
85// LDeoptimize
86// LFunctionLiteral
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +000087// LGap
88// LLabel
kasperl@chromium.orga5551262010-12-07 12:49:48 +000089// LGlobalObject
90// LGlobalReceiver
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +000091// LGoto
92// LLazyBailout
93// LLoadContextSlot
kasperl@chromium.orga5551262010-12-07 12:49:48 +000094// LLoadGlobal
95// LMaterializedLiteral
96// LArrayLiteral
97// LObjectLiteral
98// LRegExpLiteral
99// LOsrEntry
100// LParameter
101// LRegExpConstructResult
102// LStackCheck
103// LStoreKeyed
104// LStoreKeyedFastElement
105// LStoreKeyedGeneric
106// LStoreNamed
107// LStoreNamedField
108// LStoreNamedGeneric
109// LUnaryOperation
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000110// LBitNotI
111// LBranch
112// LCallNew
113// LCheckFunction
114// LCheckInstanceType
115// LCheckMap
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000116// LCheckSmi
117// LClassOfTest
118// LClassOfTestAndBranch
119// LDeleteProperty
120// LDoubleToI
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000121// LFixedArrayLength
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000122// LHasCachedArrayIndex
123// LHasCachedArrayIndexAndBranch
124// LHasInstanceType
125// LHasInstanceTypeAndBranch
126// LInteger32ToDouble
127// LIsNull
128// LIsNullAndBranch
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000129// LIsObject
130// LIsObjectAndBranch
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000131// LIsSmi
132// LIsSmiAndBranch
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000133// LJSArrayLength
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000134// LLoadNamedField
135// LLoadNamedGeneric
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000136// LLoadFunctionPrototype
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000137// LNumberTagD
138// LNumberTagI
139// LPushArgument
140// LReturn
141// LSmiTag
142// LStoreGlobal
143// LTaggedToI
144// LThrow
145// LTypeof
146// LTypeofIs
147// LTypeofIsAndBranch
148// LUnaryMathOperation
149// LValueOf
150// LUnknownOSRValue
151
152#define LITHIUM_ALL_INSTRUCTION_LIST(V) \
153 V(BinaryOperation) \
154 V(Constant) \
155 V(Call) \
156 V(MaterializedLiteral) \
157 V(StoreKeyed) \
158 V(StoreNamed) \
159 V(UnaryOperation) \
160 LITHIUM_CONCRETE_INSTRUCTION_LIST(V)
161
162
163#define LITHIUM_CONCRETE_INSTRUCTION_LIST(V) \
164 V(AccessArgumentsAt) \
165 V(AddI) \
166 V(ApplyArguments) \
167 V(ArgumentsElements) \
168 V(ArgumentsLength) \
169 V(ArithmeticD) \
170 V(ArithmeticT) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000171 V(ArrayLiteral) \
172 V(BitI) \
173 V(BitNotI) \
174 V(BoundsCheck) \
175 V(Branch) \
176 V(CallConstantFunction) \
177 V(CallFunction) \
178 V(CallGlobal) \
179 V(CallKeyed) \
180 V(CallKnownGlobal) \
181 V(CallNamed) \
182 V(CallNew) \
183 V(CallRuntime) \
184 V(CallStub) \
185 V(CheckFunction) \
186 V(CheckInstanceType) \
187 V(CheckMap) \
188 V(CheckPrototypeMaps) \
189 V(CheckSmi) \
190 V(CmpID) \
191 V(CmpIDAndBranch) \
192 V(CmpJSObjectEq) \
193 V(CmpJSObjectEqAndBranch) \
194 V(CmpMapAndBranch) \
195 V(CmpT) \
196 V(CmpTAndBranch) \
197 V(ConstantD) \
198 V(ConstantI) \
199 V(ConstantT) \
200 V(DeleteProperty) \
201 V(Deoptimize) \
202 V(DivI) \
203 V(DoubleToI) \
204 V(FunctionLiteral) \
205 V(Gap) \
206 V(GlobalObject) \
207 V(GlobalReceiver) \
208 V(Goto) \
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000209 V(FixedArrayLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000210 V(InstanceOf) \
211 V(InstanceOfAndBranch) \
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000212 V(InstanceOfKnownGlobal) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000213 V(Integer32ToDouble) \
214 V(IsNull) \
215 V(IsNullAndBranch) \
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000216 V(IsObject) \
217 V(IsObjectAndBranch) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000218 V(IsSmi) \
219 V(IsSmiAndBranch) \
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000220 V(JSArrayLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000221 V(HasInstanceType) \
222 V(HasInstanceTypeAndBranch) \
223 V(HasCachedArrayIndex) \
224 V(HasCachedArrayIndexAndBranch) \
225 V(ClassOfTest) \
226 V(ClassOfTestAndBranch) \
227 V(Label) \
228 V(LazyBailout) \
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000229 V(LoadContextSlot) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000230 V(LoadElements) \
231 V(LoadGlobal) \
232 V(LoadKeyedFastElement) \
233 V(LoadKeyedGeneric) \
234 V(LoadNamedField) \
235 V(LoadNamedGeneric) \
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000236 V(LoadFunctionPrototype) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000237 V(ModI) \
238 V(MulI) \
239 V(NumberTagD) \
240 V(NumberTagI) \
241 V(NumberUntagD) \
242 V(ObjectLiteral) \
243 V(OsrEntry) \
244 V(Parameter) \
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000245 V(Power) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000246 V(PushArgument) \
247 V(RegExpLiteral) \
248 V(Return) \
249 V(ShiftI) \
250 V(SmiTag) \
251 V(SmiUntag) \
252 V(StackCheck) \
253 V(StoreGlobal) \
254 V(StoreKeyedFastElement) \
255 V(StoreKeyedGeneric) \
256 V(StoreNamedField) \
257 V(StoreNamedGeneric) \
258 V(SubI) \
259 V(TaggedToI) \
260 V(Throw) \
261 V(Typeof) \
262 V(TypeofIs) \
263 V(TypeofIsAndBranch) \
264 V(UnaryMathOperation) \
265 V(UnknownOSRValue) \
266 V(ValueOf)
267
268
269#define DECLARE_INSTRUCTION(type) \
270 virtual bool Is##type() const { return true; } \
271 static L##type* cast(LInstruction* instr) { \
272 ASSERT(instr->Is##type()); \
273 return reinterpret_cast<L##type*>(instr); \
274 }
275
276
277#define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic) \
278 virtual void CompileToNative(LCodeGen* generator); \
279 virtual const char* Mnemonic() const { return mnemonic; } \
280 DECLARE_INSTRUCTION(type)
281
282
283#define DECLARE_HYDROGEN_ACCESSOR(type) \
284 H##type* hydrogen() const { \
285 return H##type::cast(hydrogen_value()); \
286 }
287
288
289class LInstruction: public ZoneObject {
290 public:
291 LInstruction()
292 : hydrogen_value_(NULL) { }
293 virtual ~LInstruction() { }
294
295 virtual void CompileToNative(LCodeGen* generator) = 0;
296 virtual const char* Mnemonic() const = 0;
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000297 virtual void PrintTo(StringStream* stream);
298 virtual void PrintDataTo(StringStream* stream) = 0;
299 virtual void PrintOutputOperandTo(StringStream* stream) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000300
301 // Declare virtual type testers.
302#define DECLARE_DO(type) virtual bool Is##type() const { return false; }
303 LITHIUM_ALL_INSTRUCTION_LIST(DECLARE_DO)
304#undef DECLARE_DO
305 virtual bool IsControl() const { return false; }
306
307 void set_environment(LEnvironment* env) { environment_.set(env); }
308 LEnvironment* environment() const { return environment_.get(); }
309 bool HasEnvironment() const { return environment_.is_set(); }
310
311 void set_pointer_map(LPointerMap* p) { pointer_map_.set(p); }
312 LPointerMap* pointer_map() const { return pointer_map_.get(); }
313 bool HasPointerMap() const { return pointer_map_.is_set(); }
314
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000315 virtual bool HasResult() const = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000316
317 void set_hydrogen_value(HValue* value) { hydrogen_value_ = value; }
318 HValue* hydrogen_value() const { return hydrogen_value_; }
319
320 void set_deoptimization_environment(LEnvironment* env) {
321 deoptimization_environment_.set(env);
322 }
323 LEnvironment* deoptimization_environment() const {
324 return deoptimization_environment_.get();
325 }
326 bool HasDeoptimizationEnvironment() const {
327 return deoptimization_environment_.is_set();
328 }
329
330 private:
331 SetOncePointer<LEnvironment> environment_;
332 SetOncePointer<LPointerMap> pointer_map_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000333 HValue* hydrogen_value_;
334 SetOncePointer<LEnvironment> deoptimization_environment_;
335};
336
337
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000338template<typename T, int N>
339class OperandContainer {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000340 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000341 OperandContainer() {
342 for (int i = 0; i < N; i++) elems_[i] = NULL;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000343 }
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000344 int length() const { return N; }
345 T at(int i) const { return elems_[i]; }
346 void set_at(int i, T value) { elems_[i] = value; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000347 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000348 T elems_[N];
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000349};
350
351
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000352template<typename T>
353class OperandContainer<T, 0> {
354 public:
355 int length() const { return 0; }
356 T at(int i) const {
357 UNREACHABLE();
358 return NULL;
359 }
360 void set_at(int i, T value) {
361 UNREACHABLE();
362 }
363};
364
365
366template<int R, int I, int T>
367class LTemplateInstruction: public LInstruction {
368 public:
369 // Allow 0 or 1 output operands.
370 STATIC_ASSERT(R == 0 || R == 1);
371 virtual bool HasResult() const { return R != 0; }
372 void set_result(LOperand* operand) { outputs_.set_at(0, operand); }
373 LOperand* result() const { return outputs_.at(0); }
374
375 int InputCount() const { return inputs_.length(); }
376 LOperand* InputAt(int i) const { return inputs_.at(i); }
377 void SetInputAt(int i, LOperand* operand) { inputs_.set_at(i, operand); }
378
379 int TempCount() const { return temps_.length(); }
380 LOperand* TempAt(int i) const { return temps_.at(i); }
381
382 virtual void PrintDataTo(StringStream* stream);
383 virtual void PrintOutputOperandTo(StringStream* stream);
384
385 private:
386 OperandContainer<LOperand*, R> outputs_;
387 OperandContainer<LOperand*, I> inputs_;
388 OperandContainer<LOperand*, T> temps_;
389};
390
391
392class LGap: public LTemplateInstruction<0, 0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000393 public:
394 explicit LGap(HBasicBlock* block)
395 : block_(block) {
396 parallel_moves_[BEFORE] = NULL;
397 parallel_moves_[START] = NULL;
398 parallel_moves_[END] = NULL;
399 parallel_moves_[AFTER] = NULL;
400 }
401
402 DECLARE_CONCRETE_INSTRUCTION(Gap, "gap")
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000403 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000404
405 bool IsRedundant() const;
406
407 HBasicBlock* block() const { return block_; }
408
409 enum InnerPosition {
410 BEFORE,
411 START,
412 END,
413 AFTER,
414 FIRST_INNER_POSITION = BEFORE,
415 LAST_INNER_POSITION = AFTER
416 };
417
418 LParallelMove* GetOrCreateParallelMove(InnerPosition pos) {
419 if (parallel_moves_[pos] == NULL) parallel_moves_[pos] = new LParallelMove;
420 return parallel_moves_[pos];
421 }
422
423 LParallelMove* GetParallelMove(InnerPosition pos) {
424 return parallel_moves_[pos];
425 }
426
427 private:
428 LParallelMove* parallel_moves_[LAST_INNER_POSITION + 1];
429 HBasicBlock* block_;
430};
431
432
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000433class LGoto: public LTemplateInstruction<0, 0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000434 public:
435 LGoto(int block_id, bool include_stack_check = false)
436 : block_id_(block_id), include_stack_check_(include_stack_check) { }
437
438 DECLARE_CONCRETE_INSTRUCTION(Goto, "goto")
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000439 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000440 virtual bool IsControl() const { return true; }
441
442 int block_id() const { return block_id_; }
443 bool include_stack_check() const { return include_stack_check_; }
444
445 private:
446 int block_id_;
447 bool include_stack_check_;
448};
449
450
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000451class LLazyBailout: public LTemplateInstruction<0, 0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000452 public:
453 LLazyBailout() : gap_instructions_size_(0) { }
454
455 DECLARE_CONCRETE_INSTRUCTION(LazyBailout, "lazy-bailout")
456
457 void set_gap_instructions_size(int gap_instructions_size) {
458 gap_instructions_size_ = gap_instructions_size;
459 }
460 int gap_instructions_size() { return gap_instructions_size_; }
461
462 private:
463 int gap_instructions_size_;
464};
465
466
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000467class LDeoptimize: public LTemplateInstruction<0, 0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000468 public:
469 DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize")
470};
471
472
473class LLabel: public LGap {
474 public:
475 explicit LLabel(HBasicBlock* block)
476 : LGap(block), replacement_(NULL) { }
477
478 DECLARE_CONCRETE_INSTRUCTION(Label, "label")
479
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000480 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000481
482 int block_id() const { return block()->block_id(); }
483 bool is_loop_header() const { return block()->IsLoopHeader(); }
484 Label* label() { return &label_; }
485 LLabel* replacement() const { return replacement_; }
486 void set_replacement(LLabel* label) { replacement_ = label; }
487 bool HasReplacement() const { return replacement_ != NULL; }
488
489 private:
490 Label label_;
491 LLabel* replacement_;
492};
493
494
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000495class LParameter: public LTemplateInstruction<1, 0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000496 public:
497 DECLARE_CONCRETE_INSTRUCTION(Parameter, "parameter")
498};
499
500
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000501class LCallStub: public LTemplateInstruction<1, 0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000502 public:
503 DECLARE_CONCRETE_INSTRUCTION(CallStub, "call-stub")
504 DECLARE_HYDROGEN_ACCESSOR(CallStub)
505
506 TranscendentalCache::Type transcendental_type() {
507 return hydrogen()->transcendental_type();
508 }
509};
510
511
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000512class LUnknownOSRValue: public LTemplateInstruction<1, 0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000513 public:
514 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue, "unknown-osr-value")
515};
516
517
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000518template<int R>
519class LUnaryOperation: public LTemplateInstruction<R, 1, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000520 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000521 explicit LUnaryOperation<R>(LOperand* input) {
522 this->SetInputAt(0, input);
523 }
524
525 LOperand* input() const { return this->InputAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000526
527 DECLARE_INSTRUCTION(UnaryOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000528};
529
530
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000531template<int R>
532class LBinaryOperation: public LTemplateInstruction<R, 2, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000533 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000534 LBinaryOperation(LOperand* left, LOperand* right) {
535 this->SetInputAt(0, left);
536 this->SetInputAt(1, right);
537 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000538
539 DECLARE_INSTRUCTION(BinaryOperation)
540
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000541 LOperand* left() const { return this->InputAt(0); }
542 LOperand* right() const { return this->InputAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000543};
544
545
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000546class LApplyArguments: public LTemplateInstruction<1, 4, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000547 public:
548 LApplyArguments(LOperand* function,
549 LOperand* receiver,
550 LOperand* length,
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000551 LOperand* elements) {
552 this->SetInputAt(0, function);
553 this->SetInputAt(1, receiver);
554 this->SetInputAt(2, length);
555 this->SetInputAt(3, elements);
556 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000557
558 DECLARE_CONCRETE_INSTRUCTION(ApplyArguments, "apply-arguments")
559
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000560 LOperand* function() const { return InputAt(0); }
561 LOperand* receiver() const { return InputAt(1); }
562 LOperand* length() const { return InputAt(2); }
563 LOperand* elements() const { return InputAt(3); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000564};
565
566
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000567class LAccessArgumentsAt: public LTemplateInstruction<1, 3, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000568 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000569 LAccessArgumentsAt(LOperand* arguments, LOperand* length, LOperand* index) {
570 this->SetInputAt(0, arguments);
571 this->SetInputAt(1, length);
572 this->SetInputAt(2, index);
573 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000574
575 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt, "access-arguments-at")
576
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000577 LOperand* arguments() const { return this->InputAt(0); }
578 LOperand* length() const { return this->InputAt(1); }
579 LOperand* index() const { return this->InputAt(2); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000580
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000581 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000582};
583
584
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000585class LArgumentsLength: public LUnaryOperation<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000586 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000587 explicit LArgumentsLength(LOperand* elements)
588 : LUnaryOperation<1>(elements) {}
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000589
590 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength, "arguments-length")
591};
592
593
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000594class LArgumentsElements: public LTemplateInstruction<1, 0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000595 public:
596 LArgumentsElements() { }
597
598 DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements, "arguments-elements")
599};
600
601
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000602class LModI: public LBinaryOperation<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000603 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000604 LModI(LOperand* left, LOperand* right) : LBinaryOperation<1>(left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000605
606 DECLARE_CONCRETE_INSTRUCTION(ModI, "mod-i")
607 DECLARE_HYDROGEN_ACCESSOR(Mod)
608};
609
610
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000611class LDivI: public LBinaryOperation<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000612 public:
613 LDivI(LOperand* left, LOperand* right)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000614 : LBinaryOperation<1>(left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000615
616 DECLARE_CONCRETE_INSTRUCTION(DivI, "div-i")
617 DECLARE_HYDROGEN_ACCESSOR(Div)
618};
619
620
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000621class LMulI: public LBinaryOperation<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000622 public:
623 LMulI(LOperand* left, LOperand* right, LOperand* temp)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000624 : LBinaryOperation<1>(left, right), temp_(temp) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000625
626 DECLARE_CONCRETE_INSTRUCTION(MulI, "mul-i")
627 DECLARE_HYDROGEN_ACCESSOR(Mul)
628
629 LOperand* temp() const { return temp_; }
630
631 private:
632 LOperand* temp_;
633};
634
635
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000636class LCmpID: public LBinaryOperation<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000637 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000638 LCmpID(LOperand* left, LOperand* right)
639 : LBinaryOperation<1>(left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000640
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000641 Token::Value op() const { return hydrogen()->token(); }
642 bool is_double() const {
643 return hydrogen()->GetInputRepresentation().IsDouble();
644 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000645
646 DECLARE_CONCRETE_INSTRUCTION(CmpID, "cmp-id")
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000647 DECLARE_HYDROGEN_ACCESSOR(Compare)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000648};
649
650
651class LCmpIDAndBranch: public LCmpID {
652 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000653 LCmpIDAndBranch(LOperand* left,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000654 LOperand* right,
655 int true_block_id,
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000656 int false_block_id)
657 : LCmpID(left, right),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000658 true_block_id_(true_block_id),
659 false_block_id_(false_block_id) { }
660
661 DECLARE_CONCRETE_INSTRUCTION(CmpIDAndBranch, "cmp-id-and-branch")
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000662 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000663 virtual bool IsControl() const { return true; }
664
665 int true_block_id() const { return true_block_id_; }
666 int false_block_id() const { return false_block_id_; }
667
668 private:
669 int true_block_id_;
670 int false_block_id_;
671};
672
673
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000674class LUnaryMathOperation: public LUnaryOperation<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000675 public:
676 explicit LUnaryMathOperation(LOperand* value)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000677 : LUnaryOperation<1>(value) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000678
679 DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation, "unary-math-operation")
680 DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation)
681
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000682 virtual void PrintDataTo(StringStream* stream);
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000683 BuiltinFunctionId op() const { return hydrogen()->op(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000684};
685
686
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000687class LCmpJSObjectEq: public LBinaryOperation<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000688 public:
689 LCmpJSObjectEq(LOperand* left, LOperand* right)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000690 : LBinaryOperation<1>(left, right) {}
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000691
692 DECLARE_CONCRETE_INSTRUCTION(CmpJSObjectEq, "cmp-jsobject-eq")
693};
694
695
696class LCmpJSObjectEqAndBranch: public LCmpJSObjectEq {
697 public:
698 LCmpJSObjectEqAndBranch(LOperand* left,
699 LOperand* right,
700 int true_block_id,
701 int false_block_id)
702 : LCmpJSObjectEq(left, right),
703 true_block_id_(true_block_id),
704 false_block_id_(false_block_id) { }
705
706 DECLARE_CONCRETE_INSTRUCTION(CmpJSObjectEqAndBranch,
707 "cmp-jsobject-eq-and-branch")
708
709 int true_block_id() const { return true_block_id_; }
710 int false_block_id() const { return false_block_id_; }
711
712 private:
713 int true_block_id_;
714 int false_block_id_;
715};
716
717
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000718class LIsNull: public LUnaryOperation<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000719 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000720 explicit LIsNull(LOperand* value) : LUnaryOperation<1>(value) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000721
722 DECLARE_CONCRETE_INSTRUCTION(IsNull, "is-null")
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000723 DECLARE_HYDROGEN_ACCESSOR(IsNull)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000724
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000725 bool is_strict() const { return hydrogen()->is_strict(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000726};
727
728
729class LIsNullAndBranch: public LIsNull {
730 public:
731 LIsNullAndBranch(LOperand* value,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000732 LOperand* temp,
733 int true_block_id,
734 int false_block_id)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000735 : LIsNull(value),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000736 temp_(temp),
737 true_block_id_(true_block_id),
738 false_block_id_(false_block_id) { }
739
740 DECLARE_CONCRETE_INSTRUCTION(IsNullAndBranch, "is-null-and-branch")
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000741 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000742 virtual bool IsControl() const { return true; }
743
744 int true_block_id() const { return true_block_id_; }
745 int false_block_id() const { return false_block_id_; }
746
747 LOperand* temp() const { return temp_; }
748
749 private:
750 LOperand* temp_;
751 int true_block_id_;
752 int false_block_id_;
753};
754
755
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000756class LIsObject: public LUnaryOperation<1> {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000757 public:
758 LIsObject(LOperand* value, LOperand* temp)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000759 : LUnaryOperation<1>(value), temp_(temp) {}
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000760
761 DECLARE_CONCRETE_INSTRUCTION(IsObject, "is-object")
762
763 LOperand* temp() const { return temp_; }
764
765 private:
766 LOperand* temp_;
767};
768
769
770class LIsObjectAndBranch: public LIsObject {
771 public:
772 LIsObjectAndBranch(LOperand* value,
773 LOperand* temp,
774 LOperand* temp2,
775 int true_block_id,
776 int false_block_id)
777 : LIsObject(value, temp),
778 temp2_(temp2),
779 true_block_id_(true_block_id),
780 false_block_id_(false_block_id) { }
781
782 DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch, "is-object-and-branch")
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000783 virtual void PrintDataTo(StringStream* stream);
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000784 virtual bool IsControl() const { return true; }
785
786 int true_block_id() const { return true_block_id_; }
787 int false_block_id() const { return false_block_id_; }
788
789 LOperand* temp2() const { return temp2_; }
790
791 private:
792 LOperand* temp2_;
793 int true_block_id_;
794 int false_block_id_;
795};
796
797
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000798class LIsSmi: public LUnaryOperation<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000799 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000800 explicit LIsSmi(LOperand* value) : LUnaryOperation<1>(value) {}
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000801
802 DECLARE_CONCRETE_INSTRUCTION(IsSmi, "is-smi")
803 DECLARE_HYDROGEN_ACCESSOR(IsSmi)
804};
805
806
807class LIsSmiAndBranch: public LIsSmi {
808 public:
809 LIsSmiAndBranch(LOperand* value,
810 int true_block_id,
811 int false_block_id)
812 : LIsSmi(value),
813 true_block_id_(true_block_id),
814 false_block_id_(false_block_id) { }
815
816 DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch, "is-smi-and-branch")
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000817 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000818 virtual bool IsControl() const { return true; }
819
820 int true_block_id() const { return true_block_id_; }
821 int false_block_id() const { return false_block_id_; }
822
823 private:
824 int true_block_id_;
825 int false_block_id_;
826};
827
828
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000829class LHasInstanceType: public LUnaryOperation<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000830 public:
831 explicit LHasInstanceType(LOperand* value)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000832 : LUnaryOperation<1>(value) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000833
834 DECLARE_CONCRETE_INSTRUCTION(HasInstanceType, "has-instance-type")
835 DECLARE_HYDROGEN_ACCESSOR(HasInstanceType)
836
837 InstanceType TestType(); // The type to test against when generating code.
838 Condition BranchCondition(); // The branch condition for 'true'.
839};
840
841
842class LHasInstanceTypeAndBranch: public LHasInstanceType {
843 public:
844 LHasInstanceTypeAndBranch(LOperand* value,
845 LOperand* temporary,
846 int true_block_id,
847 int false_block_id)
848 : LHasInstanceType(value),
849 temp_(temporary),
850 true_block_id_(true_block_id),
851 false_block_id_(false_block_id) { }
852
853 DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch,
854 "has-instance-type-and-branch")
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000855 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000856 virtual bool IsControl() const { return true; }
857
858 int true_block_id() const { return true_block_id_; }
859 int false_block_id() const { return false_block_id_; }
860
861 LOperand* temp() { return temp_; }
862
863 private:
864 LOperand* temp_;
865 int true_block_id_;
866 int false_block_id_;
867};
868
869
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000870class LHasCachedArrayIndex: public LUnaryOperation<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000871 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000872 explicit LHasCachedArrayIndex(LOperand* value) : LUnaryOperation<1>(value) {}
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000873
874 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndex, "has-cached-array-index")
875 DECLARE_HYDROGEN_ACCESSOR(HasCachedArrayIndex)
876};
877
878
879class LHasCachedArrayIndexAndBranch: public LHasCachedArrayIndex {
880 public:
881 LHasCachedArrayIndexAndBranch(LOperand* value,
882 int true_block_id,
883 int false_block_id)
884 : LHasCachedArrayIndex(value),
885 true_block_id_(true_block_id),
886 false_block_id_(false_block_id) { }
887
888 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndexAndBranch,
889 "has-cached-array-index-and-branch")
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000890 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000891 virtual bool IsControl() const { return true; }
892
893 int true_block_id() const { return true_block_id_; }
894 int false_block_id() const { return false_block_id_; }
895
896 private:
897 int true_block_id_;
898 int false_block_id_;
899};
900
901
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000902class LClassOfTest: public LUnaryOperation<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000903 public:
904 LClassOfTest(LOperand* value, LOperand* temp)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000905 : LUnaryOperation<1>(value), temporary_(temp) {}
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000906
907 DECLARE_CONCRETE_INSTRUCTION(ClassOfTest, "class-of-test")
908 DECLARE_HYDROGEN_ACCESSOR(ClassOfTest)
909
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000910 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000911
912 LOperand* temporary() { return temporary_; }
913
914 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000915 LOperand* temporary_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000916};
917
918
919class LClassOfTestAndBranch: public LClassOfTest {
920 public:
921 LClassOfTestAndBranch(LOperand* value,
922 LOperand* temporary,
923 LOperand* temporary2,
924 int true_block_id,
925 int false_block_id)
926 : LClassOfTest(value, temporary),
927 temporary2_(temporary2),
928 true_block_id_(true_block_id),
929 false_block_id_(false_block_id) { }
930
931 DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch,
932 "class-of-test-and-branch")
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000933 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000934 virtual bool IsControl() const { return true; }
935
936 int true_block_id() const { return true_block_id_; }
937 int false_block_id() const { return false_block_id_; }
938 LOperand* temporary2() { return temporary2_; }
939
940 private:
941 LOperand* temporary2_;
942 int true_block_id_;
943 int false_block_id_;
944};
945
946
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000947class LCmpT: public LBinaryOperation<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000948 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000949 LCmpT(LOperand* left, LOperand* right) : LBinaryOperation<1>(left, right) {}
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000950
951 DECLARE_CONCRETE_INSTRUCTION(CmpT, "cmp-t")
952 DECLARE_HYDROGEN_ACCESSOR(Compare)
953
954 Token::Value op() const { return hydrogen()->token(); }
955};
956
957
958class LCmpTAndBranch: public LCmpT {
959 public:
960 LCmpTAndBranch(LOperand* left,
961 LOperand* right,
962 int true_block_id,
963 int false_block_id)
964 : LCmpT(left, right),
965 true_block_id_(true_block_id),
966 false_block_id_(false_block_id) { }
967
968 DECLARE_CONCRETE_INSTRUCTION(CmpTAndBranch, "cmp-t-and-branch")
969
970 int true_block_id() const { return true_block_id_; }
971 int false_block_id() const { return false_block_id_; }
972
973 private:
974 int true_block_id_;
975 int false_block_id_;
976};
977
978
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000979class LInstanceOf: public LBinaryOperation<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000980 public:
981 LInstanceOf(LOperand* left, LOperand* right)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000982 : LBinaryOperation<1>(left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000983
984 DECLARE_CONCRETE_INSTRUCTION(InstanceOf, "instance-of")
985};
986
987
988class LInstanceOfAndBranch: public LInstanceOf {
989 public:
990 LInstanceOfAndBranch(LOperand* left,
991 LOperand* right,
992 int true_block_id,
993 int false_block_id)
994 : LInstanceOf(left, right),
995 true_block_id_(true_block_id),
996 false_block_id_(false_block_id) { }
997
998 DECLARE_CONCRETE_INSTRUCTION(InstanceOfAndBranch, "instance-of-and-branch")
999
1000 int true_block_id() const { return true_block_id_; }
1001 int false_block_id() const { return false_block_id_; }
1002
1003 private:
1004 int true_block_id_;
1005 int false_block_id_;
1006};
1007
1008
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001009class LInstanceOfKnownGlobal: public LUnaryOperation<1> {
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00001010 public:
1011 LInstanceOfKnownGlobal(LOperand* left, LOperand* temp)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001012 : LUnaryOperation<1>(left), temp_(temp) { }
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00001013
1014 DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal,
1015 "instance-of-known-global")
1016 DECLARE_HYDROGEN_ACCESSOR(InstanceOfKnownGlobal)
1017
1018 Handle<JSFunction> function() const { return hydrogen()->function(); }
1019 LOperand* temp() const { return temp_; }
1020
1021 private:
1022 LOperand* temp_;
1023};
1024
1025
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001026class LBoundsCheck: public LBinaryOperation<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001027 public:
1028 LBoundsCheck(LOperand* index, LOperand* length)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001029 : LBinaryOperation<0>(index, length) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001030
1031 LOperand* index() const { return left(); }
1032 LOperand* length() const { return right(); }
1033
1034 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck, "bounds-check")
1035};
1036
1037
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001038class LBitI: public LBinaryOperation<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001039 public:
1040 LBitI(Token::Value op, LOperand* left, LOperand* right)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001041 : LBinaryOperation<1>(left, right), op_(op) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001042
1043 Token::Value op() const { return op_; }
1044
1045 DECLARE_CONCRETE_INSTRUCTION(BitI, "bit-i")
1046
1047 private:
1048 Token::Value op_;
1049};
1050
1051
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001052class LShiftI: public LBinaryOperation<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001053 public:
1054 LShiftI(Token::Value op, LOperand* left, LOperand* right, bool can_deopt)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001055 : LBinaryOperation<1>(left, right), op_(op), can_deopt_(can_deopt) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001056
1057 Token::Value op() const { return op_; }
1058
1059 bool can_deopt() const { return can_deopt_; }
1060
1061 DECLARE_CONCRETE_INSTRUCTION(ShiftI, "shift-i")
1062
1063 private:
1064 Token::Value op_;
1065 bool can_deopt_;
1066};
1067
1068
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001069class LSubI: public LBinaryOperation<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001070 public:
1071 LSubI(LOperand* left, LOperand* right)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001072 : LBinaryOperation<1>(left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001073
1074 DECLARE_CONCRETE_INSTRUCTION(SubI, "sub-i")
1075 DECLARE_HYDROGEN_ACCESSOR(Sub)
1076};
1077
1078
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001079class LConstant: public LTemplateInstruction<1, 0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001080 DECLARE_INSTRUCTION(Constant)
1081};
1082
1083
1084class LConstantI: public LConstant {
1085 public:
1086 explicit LConstantI(int32_t value) : value_(value) { }
1087 int32_t value() const { return value_; }
1088
1089 DECLARE_CONCRETE_INSTRUCTION(ConstantI, "constant-i")
1090
1091 private:
1092 int32_t value_;
1093};
1094
1095
1096class LConstantD: public LConstant {
1097 public:
1098 explicit LConstantD(double value) : value_(value) { }
1099 double value() const { return value_; }
1100
1101 DECLARE_CONCRETE_INSTRUCTION(ConstantD, "constant-d")
1102
1103 private:
1104 double value_;
1105};
1106
1107
1108class LConstantT: public LConstant {
1109 public:
1110 explicit LConstantT(Handle<Object> value) : value_(value) { }
1111 Handle<Object> value() const { return value_; }
1112
1113 DECLARE_CONCRETE_INSTRUCTION(ConstantT, "constant-t")
1114
1115 private:
1116 Handle<Object> value_;
1117};
1118
1119
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001120class LBranch: public LUnaryOperation<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001121 public:
1122 LBranch(LOperand* input, int true_block_id, int false_block_id)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001123 : LUnaryOperation<0>(input),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001124 true_block_id_(true_block_id),
1125 false_block_id_(false_block_id) { }
1126
1127 DECLARE_CONCRETE_INSTRUCTION(Branch, "branch")
1128 DECLARE_HYDROGEN_ACCESSOR(Value)
1129
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001130 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001131 virtual bool IsControl() const { return true; }
1132
1133 int true_block_id() const { return true_block_id_; }
1134 int false_block_id() const { return false_block_id_; }
1135
1136 private:
1137 int true_block_id_;
1138 int false_block_id_;
1139};
1140
1141
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001142class LCmpMapAndBranch: public LUnaryOperation<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001143 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001144 explicit LCmpMapAndBranch(LOperand* value) : LUnaryOperation<0>(value) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001145
1146 DECLARE_CONCRETE_INSTRUCTION(CmpMapAndBranch, "cmp-map-and-branch")
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00001147 DECLARE_HYDROGEN_ACCESSOR(CompareMapAndBranch)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001148
1149 virtual bool IsControl() const { return true; }
1150
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00001151 Handle<Map> map() const { return hydrogen()->map(); }
1152 int true_block_id() const {
1153 return hydrogen()->true_destination()->block_id();
1154 }
1155 int false_block_id() const {
1156 return hydrogen()->false_destination()->block_id();
1157 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001158};
1159
1160
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001161class LJSArrayLength: public LUnaryOperation<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001162 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001163 explicit LJSArrayLength(LOperand* input) : LUnaryOperation<1>(input) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001164
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001165 DECLARE_CONCRETE_INSTRUCTION(JSArrayLength, "js-array-length")
1166 DECLARE_HYDROGEN_ACCESSOR(JSArrayLength)
1167};
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001168
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001169
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001170class LFixedArrayLength: public LUnaryOperation<1> {
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001171 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001172 explicit LFixedArrayLength(LOperand* input) : LUnaryOperation<1>(input) { }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001173
1174 DECLARE_CONCRETE_INSTRUCTION(FixedArrayLength, "fixed-array-length")
1175 DECLARE_HYDROGEN_ACCESSOR(FixedArrayLength)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001176};
1177
1178
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001179class LValueOf: public LUnaryOperation<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001180 public:
1181 LValueOf(LOperand* input, LOperand* temporary)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001182 : LUnaryOperation<1>(input), temporary_(temporary) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001183
1184 LOperand* temporary() const { return temporary_; }
1185
1186 DECLARE_CONCRETE_INSTRUCTION(ValueOf, "value-of")
1187 DECLARE_HYDROGEN_ACCESSOR(ValueOf)
1188
1189 private:
1190 LOperand* temporary_;
1191};
1192
1193
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001194class LThrow: public LUnaryOperation<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001195 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001196 explicit LThrow(LOperand* value) : LUnaryOperation<0>(value) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001197
1198 DECLARE_CONCRETE_INSTRUCTION(Throw, "throw")
1199};
1200
1201
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001202class LBitNotI: public LUnaryOperation<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001203 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001204 explicit LBitNotI(LOperand* input) : LUnaryOperation<1>(input) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001205
1206 DECLARE_CONCRETE_INSTRUCTION(BitNotI, "bit-not-i")
1207};
1208
1209
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001210class LAddI: public LBinaryOperation<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001211 public:
1212 LAddI(LOperand* left, LOperand* right)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001213 : LBinaryOperation<1>(left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001214
1215 DECLARE_CONCRETE_INSTRUCTION(AddI, "add-i")
1216 DECLARE_HYDROGEN_ACCESSOR(Add)
1217};
1218
1219
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001220class LPower: public LBinaryOperation<1> {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001221 public:
1222 LPower(LOperand* left, LOperand* right)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001223 : LBinaryOperation<1>(left, right) { }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001224
1225 DECLARE_CONCRETE_INSTRUCTION(Power, "power")
1226 DECLARE_HYDROGEN_ACCESSOR(Power)
1227};
1228
1229
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001230class LArithmeticD: public LBinaryOperation<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001231 public:
1232 LArithmeticD(Token::Value op, LOperand* left, LOperand* right)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001233 : LBinaryOperation<1>(left, right), op_(op) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001234
1235 Token::Value op() const { return op_; }
1236
1237 virtual void CompileToNative(LCodeGen* generator);
1238 virtual const char* Mnemonic() const;
1239
1240 private:
1241 Token::Value op_;
1242};
1243
1244
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001245class LArithmeticT: public LBinaryOperation<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001246 public:
1247 LArithmeticT(Token::Value op, LOperand* left, LOperand* right)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001248 : LBinaryOperation<1>(left, right), op_(op) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001249
1250 virtual void CompileToNative(LCodeGen* generator);
1251 virtual const char* Mnemonic() const;
1252
1253 Token::Value op() const { return op_; }
1254
1255 private:
1256 Token::Value op_;
1257};
1258
1259
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001260class LReturn: public LUnaryOperation<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001261 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001262 explicit LReturn(LOperand* use) : LUnaryOperation<0>(use) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001263
1264 DECLARE_CONCRETE_INSTRUCTION(Return, "return")
1265};
1266
1267
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001268class LLoadNamedField: public LUnaryOperation<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001269 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001270 explicit LLoadNamedField(LOperand* object) : LUnaryOperation<1>(object) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001271
1272 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load-named-field")
1273 DECLARE_HYDROGEN_ACCESSOR(LoadNamedField)
1274};
1275
1276
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001277class LLoadNamedGeneric: public LUnaryOperation<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001278 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001279 explicit LLoadNamedGeneric(LOperand* object) : LUnaryOperation<1>(object) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001280
1281 DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric, "load-named-generic")
1282 DECLARE_HYDROGEN_ACCESSOR(LoadNamedGeneric)
1283
1284 LOperand* object() const { return input(); }
1285 Handle<Object> name() const { return hydrogen()->name(); }
1286};
1287
1288
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001289class LLoadFunctionPrototype: public LUnaryOperation<1> {
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001290 public:
1291 LLoadFunctionPrototype(LOperand* function, LOperand* temporary)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001292 : LUnaryOperation<1>(function), temporary_(temporary) { }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001293
1294 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype, "load-function-prototype")
1295 DECLARE_HYDROGEN_ACCESSOR(LoadFunctionPrototype)
1296
1297 LOperand* function() const { return input(); }
1298 LOperand* temporary() const { return temporary_; }
1299
1300 private:
1301 LOperand* temporary_;
1302};
1303
1304
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001305class LLoadElements: public LUnaryOperation<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001306 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001307 explicit LLoadElements(LOperand* obj) : LUnaryOperation<1>(obj) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001308
1309 DECLARE_CONCRETE_INSTRUCTION(LoadElements, "load-elements")
1310};
1311
1312
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001313class LLoadKeyedFastElement: public LBinaryOperation<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001314 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001315 LLoadKeyedFastElement(LOperand* elements, LOperand* key)
1316 : LBinaryOperation<1>(elements, key) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001317
1318 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement, "load-keyed-fast-element")
1319 DECLARE_HYDROGEN_ACCESSOR(LoadKeyedFastElement)
1320
1321 LOperand* elements() const { return left(); }
1322 LOperand* key() const { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001323};
1324
1325
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001326class LLoadKeyedGeneric: public LBinaryOperation<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001327 public:
1328 LLoadKeyedGeneric(LOperand* obj, LOperand* key)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001329 : LBinaryOperation<1>(obj, key) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001330
1331 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric, "load-keyed-generic")
1332
1333 LOperand* object() const { return left(); }
1334 LOperand* key() const { return right(); }
1335};
1336
1337
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001338class LLoadGlobal: public LTemplateInstruction<1, 0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001339 public:
1340 DECLARE_CONCRETE_INSTRUCTION(LoadGlobal, "load-global")
1341 DECLARE_HYDROGEN_ACCESSOR(LoadGlobal)
1342};
1343
1344
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001345class LStoreGlobal: public LUnaryOperation<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001346 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001347 explicit LStoreGlobal(LOperand* value) : LUnaryOperation<0>(value) {}
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001348
1349 DECLARE_CONCRETE_INSTRUCTION(StoreGlobal, "store-global")
1350 DECLARE_HYDROGEN_ACCESSOR(StoreGlobal)
1351};
1352
1353
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001354class LLoadContextSlot: public LTemplateInstruction<1, 0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001355 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001356 DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot, "load-context-slot")
1357 DECLARE_HYDROGEN_ACCESSOR(LoadContextSlot)
1358
1359 int context_chain_length() const {
1360 return hydrogen()->context_chain_length();
1361 }
1362 int slot_index() const { return hydrogen()->slot_index(); }
1363
1364 virtual void PrintDataTo(StringStream* stream);
1365};
1366
1367
1368class LPushArgument: public LUnaryOperation<0> {
1369 public:
1370 explicit LPushArgument(LOperand* argument) : LUnaryOperation<0>(argument) {}
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001371
1372 DECLARE_CONCRETE_INSTRUCTION(PushArgument, "push-argument")
1373};
1374
1375
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001376class LGlobalObject: public LTemplateInstruction<1, 0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001377 public:
1378 DECLARE_CONCRETE_INSTRUCTION(GlobalObject, "global-object")
1379};
1380
1381
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001382class LGlobalReceiver: public LTemplateInstruction<1, 0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001383 public:
1384 DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver, "global-receiver")
1385};
1386
1387
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001388class LCallConstantFunction: public LTemplateInstruction<1, 0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001389 public:
1390 DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction, "call-constant-function")
1391 DECLARE_HYDROGEN_ACCESSOR(CallConstantFunction)
1392
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001393 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001394
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001395 Handle<JSFunction> function() { return hydrogen()->function(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001396 int arity() const { return hydrogen()->argument_count() - 1; }
1397};
1398
1399
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001400class LCallKeyed: public LTemplateInstruction<1, 0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001401 public:
1402 DECLARE_CONCRETE_INSTRUCTION(CallKeyed, "call-keyed")
1403 DECLARE_HYDROGEN_ACCESSOR(CallKeyed)
1404
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001405 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001406
1407 int arity() const { return hydrogen()->argument_count() - 1; }
1408};
1409
1410
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001411class LCallNamed: public LTemplateInstruction<1, 0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001412 public:
1413 DECLARE_CONCRETE_INSTRUCTION(CallNamed, "call-named")
1414 DECLARE_HYDROGEN_ACCESSOR(CallNamed)
1415
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001416 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001417
1418 Handle<String> name() const { return hydrogen()->name(); }
1419 int arity() const { return hydrogen()->argument_count() - 1; }
1420};
1421
1422
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001423class LCallFunction: public LTemplateInstruction<1, 0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001424 public:
1425 DECLARE_CONCRETE_INSTRUCTION(CallFunction, "call-function")
1426 DECLARE_HYDROGEN_ACCESSOR(CallFunction)
1427
1428 int arity() const { return hydrogen()->argument_count() - 2; }
1429};
1430
1431
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001432class LCallGlobal: public LTemplateInstruction<1, 0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001433 public:
1434 DECLARE_CONCRETE_INSTRUCTION(CallGlobal, "call-global")
1435 DECLARE_HYDROGEN_ACCESSOR(CallGlobal)
1436
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001437 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001438
1439 Handle<String> name() const {return hydrogen()->name(); }
1440 int arity() const { return hydrogen()->argument_count() - 1; }
1441};
1442
1443
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001444class LCallKnownGlobal: public LTemplateInstruction<1, 0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001445 public:
1446 DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal, "call-known-global")
1447 DECLARE_HYDROGEN_ACCESSOR(CallKnownGlobal)
1448
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001449 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001450
1451 Handle<JSFunction> target() const { return hydrogen()->target(); }
1452 int arity() const { return hydrogen()->argument_count() - 1; }
1453};
1454
1455
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001456class LCallNew: public LUnaryOperation<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001457 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001458 explicit LCallNew(LOperand* constructor) : LUnaryOperation<1>(constructor) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001459
1460 DECLARE_CONCRETE_INSTRUCTION(CallNew, "call-new")
1461 DECLARE_HYDROGEN_ACCESSOR(CallNew)
1462
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001463 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001464
1465 int arity() const { return hydrogen()->argument_count() - 1; }
1466};
1467
1468
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001469class LCallRuntime: public LTemplateInstruction<1, 0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001470 public:
1471 DECLARE_CONCRETE_INSTRUCTION(CallRuntime, "call-runtime")
1472 DECLARE_HYDROGEN_ACCESSOR(CallRuntime)
1473
1474 Runtime::Function* function() const { return hydrogen()->function(); }
1475 int arity() const { return hydrogen()->argument_count(); }
1476};
1477
1478
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001479class LInteger32ToDouble: public LUnaryOperation<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001480 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001481 explicit LInteger32ToDouble(LOperand* use) : LUnaryOperation<1>(use) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001482
1483 DECLARE_CONCRETE_INSTRUCTION(Integer32ToDouble, "int32-to-double")
1484};
1485
1486
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001487class LNumberTagI: public LUnaryOperation<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001488 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001489 explicit LNumberTagI(LOperand* use) : LUnaryOperation<1>(use) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001490
1491 DECLARE_CONCRETE_INSTRUCTION(NumberTagI, "number-tag-i")
1492};
1493
1494
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001495class LNumberTagD: public LUnaryOperation<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001496 public:
1497 explicit LNumberTagD(LOperand* value, LOperand* temp)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001498 : LUnaryOperation<1>(value), temp_(temp) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001499
1500 DECLARE_CONCRETE_INSTRUCTION(NumberTagD, "number-tag-d")
1501
1502 LOperand* temp() const { return temp_; }
1503
1504 private:
1505 LOperand* temp_;
1506};
1507
1508
1509// Sometimes truncating conversion from a tagged value to an int32.
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001510class LDoubleToI: public LUnaryOperation<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001511 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001512 LDoubleToI(LOperand* value, LOperand* temporary)
1513 : LUnaryOperation<1>(value), temporary_(temporary) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001514
1515 DECLARE_CONCRETE_INSTRUCTION(DoubleToI, "double-to-i")
1516 DECLARE_HYDROGEN_ACCESSOR(Change)
1517
1518 bool truncating() { return hydrogen()->CanTruncateToInt32(); }
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001519 LOperand* temporary() const { return temporary_; }
1520
1521 private:
1522 LOperand* temporary_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001523};
1524
1525
1526// Truncating conversion from a tagged value to an int32.
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001527class LTaggedToI: public LUnaryOperation<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001528 public:
1529 LTaggedToI(LOperand* value, LOperand* temp)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001530 : LUnaryOperation<1>(value), temp_(temp) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001531
1532 DECLARE_CONCRETE_INSTRUCTION(TaggedToI, "tagged-to-i")
1533 DECLARE_HYDROGEN_ACCESSOR(Change)
1534
1535 bool truncating() { return hydrogen()->CanTruncateToInt32(); }
1536 LOperand* temp() const { return temp_; }
1537
1538 private:
1539 LOperand* temp_;
1540};
1541
1542
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001543class LSmiTag: public LUnaryOperation<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001544 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001545 explicit LSmiTag(LOperand* use) : LUnaryOperation<1>(use) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001546
1547 DECLARE_CONCRETE_INSTRUCTION(SmiTag, "smi-tag")
1548};
1549
1550
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001551class LNumberUntagD: public LUnaryOperation<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001552 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001553 explicit LNumberUntagD(LOperand* value) : LUnaryOperation<1>(value) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001554
1555 DECLARE_CONCRETE_INSTRUCTION(NumberUntagD, "double-untag")
1556};
1557
1558
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001559class LSmiUntag: public LUnaryOperation<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001560 public:
1561 LSmiUntag(LOperand* use, bool needs_check)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001562 : LUnaryOperation<1>(use), needs_check_(needs_check) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001563
1564 DECLARE_CONCRETE_INSTRUCTION(SmiUntag, "smi-untag")
1565
1566 bool needs_check() const { return needs_check_; }
1567
1568 private:
1569 bool needs_check_;
1570};
1571
1572
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001573class LStoreNamed: public LTemplateInstruction<0, 2, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001574 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001575 LStoreNamed(LOperand* obj, LOperand* val) {
1576 this->SetInputAt(0, obj);
1577 this->SetInputAt(1, val);
1578 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001579
1580 DECLARE_INSTRUCTION(StoreNamed)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001581 DECLARE_HYDROGEN_ACCESSOR(StoreNamed)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001582
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001583 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001584
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001585 LOperand* object() const { return this->InputAt(0); }
1586 LOperand* value() const { return this->InputAt(1); }
1587 Handle<Object> name() const { return hydrogen()->name(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001588};
1589
1590
1591class LStoreNamedField: public LStoreNamed {
1592 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001593 LStoreNamedField(LOperand* obj, LOperand* val, LOperand* temp)
1594 : LStoreNamed(obj, val), temp_(temp) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001595
1596 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store-named-field")
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001597 DECLARE_HYDROGEN_ACCESSOR(StoreNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001598
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001599 bool is_in_object() { return hydrogen()->is_in_object(); }
1600 int offset() { return hydrogen()->offset(); }
1601 bool needs_write_barrier() { return hydrogen()->NeedsWriteBarrier(); }
1602 Handle<Map> transition() const { return hydrogen()->transition(); }
1603
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001604 LOperand* temp() { return temp_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001605
1606 private:
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001607 LOperand* temp_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001608};
1609
1610
1611class LStoreNamedGeneric: public LStoreNamed {
1612 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001613 LStoreNamedGeneric(LOperand* obj, LOperand* val)
1614 : LStoreNamed(obj, val) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001615
1616 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric, "store-named-generic")
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001617 DECLARE_HYDROGEN_ACCESSOR(StoreNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001618};
1619
1620
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001621class LStoreKeyed: public LTemplateInstruction<0, 3, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001622 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001623 LStoreKeyed(LOperand* obj, LOperand* key, LOperand* val) {
1624 this->SetInputAt(0, obj);
1625 this->SetInputAt(1, key);
1626 this->SetInputAt(2, val);
1627 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001628
1629 DECLARE_INSTRUCTION(StoreKeyed)
1630
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001631 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001632
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001633 LOperand* object() const { return this->InputAt(0); }
1634 LOperand* key() const { return this->InputAt(1); }
1635 LOperand* value() const { return this->InputAt(2); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001636};
1637
1638
1639class LStoreKeyedFastElement: public LStoreKeyed {
1640 public:
1641 LStoreKeyedFastElement(LOperand* obj, LOperand* key, LOperand* val)
1642 : LStoreKeyed(obj, key, val) {}
1643
1644 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement,
1645 "store-keyed-fast-element")
1646 DECLARE_HYDROGEN_ACCESSOR(StoreKeyedFastElement)
1647};
1648
1649
1650class LStoreKeyedGeneric: public LStoreKeyed {
1651 public:
1652 LStoreKeyedGeneric(LOperand* obj, LOperand* key, LOperand* val)
1653 : LStoreKeyed(obj, key, val) { }
1654
1655 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric, "store-keyed-generic")
1656};
1657
1658
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001659class LCheckFunction: public LUnaryOperation<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001660 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001661 explicit LCheckFunction(LOperand* use) : LUnaryOperation<0>(use) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001662
1663 DECLARE_CONCRETE_INSTRUCTION(CheckFunction, "check-function")
1664 DECLARE_HYDROGEN_ACCESSOR(CheckFunction)
1665};
1666
1667
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001668class LCheckInstanceType: public LUnaryOperation<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001669 public:
1670 LCheckInstanceType(LOperand* use, LOperand* temp)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001671 : LUnaryOperation<0>(use), temp_(temp) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001672
1673 DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType, "check-instance-type")
1674 DECLARE_HYDROGEN_ACCESSOR(CheckInstanceType)
1675
1676 LOperand* temp() const { return temp_; }
1677
1678 private:
1679 LOperand* temp_;
1680};
1681
1682
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001683class LCheckMap: public LUnaryOperation<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001684 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001685 explicit LCheckMap(LOperand* use) : LUnaryOperation<0>(use) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001686
1687 DECLARE_CONCRETE_INSTRUCTION(CheckMap, "check-map")
1688 DECLARE_HYDROGEN_ACCESSOR(CheckMap)
1689};
1690
1691
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001692class LCheckPrototypeMaps: public LTemplateInstruction<0, 0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001693 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001694 explicit LCheckPrototypeMaps(LOperand* temp) : temp_(temp) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001695
1696 DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps, "check-prototype-maps")
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001697 DECLARE_HYDROGEN_ACCESSOR(CheckPrototypeMaps)
1698
1699 Handle<JSObject> prototype() const { return hydrogen()->prototype(); }
1700 Handle<JSObject> holder() const { return hydrogen()->holder(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001701
1702 LOperand* temp() const { return temp_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001703
1704 private:
1705 LOperand* temp_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001706};
1707
1708
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001709class LCheckSmi: public LUnaryOperation<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001710 public:
1711 LCheckSmi(LOperand* use, Condition condition)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001712 : LUnaryOperation<0>(use), condition_(condition) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001713
1714 Condition condition() const { return condition_; }
1715
1716 virtual void CompileToNative(LCodeGen* generator);
1717 virtual const char* Mnemonic() const {
1718 return (condition_ == zero) ? "check-non-smi" : "check-smi";
1719 }
1720
1721 private:
1722 Condition condition_;
1723};
1724
1725
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001726class LMaterializedLiteral: public LTemplateInstruction<1, 0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001727 public:
1728 DECLARE_INSTRUCTION(MaterializedLiteral)
1729};
1730
1731
1732class LArrayLiteral: public LMaterializedLiteral {
1733 public:
1734 DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral, "array-literal")
1735 DECLARE_HYDROGEN_ACCESSOR(ArrayLiteral)
1736};
1737
1738
1739class LObjectLiteral: public LMaterializedLiteral {
1740 public:
1741 DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral, "object-literal")
1742 DECLARE_HYDROGEN_ACCESSOR(ObjectLiteral)
1743};
1744
1745
1746class LRegExpLiteral: public LMaterializedLiteral {
1747 public:
1748 DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral, "regexp-literal")
1749 DECLARE_HYDROGEN_ACCESSOR(RegExpLiteral)
1750};
1751
1752
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001753class LFunctionLiteral: public LTemplateInstruction<1, 0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001754 public:
1755 DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral, "function-literal")
1756 DECLARE_HYDROGEN_ACCESSOR(FunctionLiteral)
1757
1758 Handle<SharedFunctionInfo> shared_info() { return hydrogen()->shared_info(); }
1759};
1760
1761
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001762class LTypeof: public LUnaryOperation<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001763 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001764 explicit LTypeof(LOperand* input) : LUnaryOperation<1>(input) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001765
1766 DECLARE_CONCRETE_INSTRUCTION(Typeof, "typeof")
1767};
1768
1769
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001770class LTypeofIs: public LUnaryOperation<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001771 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001772 explicit LTypeofIs(LOperand* input) : LUnaryOperation<1>(input) { }
1773 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001774
1775 DECLARE_CONCRETE_INSTRUCTION(TypeofIs, "typeof-is")
1776 DECLARE_HYDROGEN_ACCESSOR(TypeofIs)
1777
1778 Handle<String> type_literal() { return hydrogen()->type_literal(); }
1779};
1780
1781
1782class LTypeofIsAndBranch: public LTypeofIs {
1783 public:
1784 LTypeofIsAndBranch(LOperand* value,
1785 int true_block_id,
1786 int false_block_id)
1787 : LTypeofIs(value),
1788 true_block_id_(true_block_id),
1789 false_block_id_(false_block_id) { }
1790
1791 DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch, "typeof-is-and-branch")
1792
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001793 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001794 virtual bool IsControl() const { return true; }
1795
1796 int true_block_id() const { return true_block_id_; }
1797 int false_block_id() const { return false_block_id_; }
1798
1799 private:
1800 int true_block_id_;
1801 int false_block_id_;
1802};
1803
1804
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001805class LDeleteProperty: public LBinaryOperation<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001806 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001807 LDeleteProperty(LOperand* obj, LOperand* key)
1808 : LBinaryOperation<1>(obj, key) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001809
1810 DECLARE_CONCRETE_INSTRUCTION(DeleteProperty, "delete-property")
1811
1812 LOperand* object() const { return left(); }
1813 LOperand* key() const { return right(); }
1814};
1815
1816
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001817class LOsrEntry: public LTemplateInstruction<0, 0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001818 public:
1819 LOsrEntry();
1820
1821 DECLARE_CONCRETE_INSTRUCTION(OsrEntry, "osr-entry")
1822
1823 LOperand** SpilledRegisterArray() { return register_spills_; }
1824 LOperand** SpilledDoubleRegisterArray() { return double_register_spills_; }
1825
1826 void MarkSpilledRegister(int allocation_index, LOperand* spill_operand);
1827 void MarkSpilledDoubleRegister(int allocation_index,
1828 LOperand* spill_operand);
1829
1830 private:
1831 // Arrays of spill slot operands for registers with an assigned spill
1832 // slot, i.e., that must also be restored to the spill slot on OSR entry.
1833 // NULL if the register has no assigned spill slot. Indexed by allocation
1834 // index.
1835 LOperand* register_spills_[Register::kNumAllocatableRegisters];
1836 LOperand* double_register_spills_[DoubleRegister::kNumAllocatableRegisters];
1837};
1838
1839
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001840class LStackCheck: public LTemplateInstruction<0, 0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001841 public:
1842 DECLARE_CONCRETE_INSTRUCTION(StackCheck, "stack-check")
1843};
1844
1845
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001846class LChunkBuilder;
1847class LChunk: public ZoneObject {
1848 public:
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00001849 explicit LChunk(HGraph* graph)
1850 : spill_slot_count_(0),
1851 graph_(graph),
1852 instructions_(32),
1853 pointer_maps_(8),
1854 inlined_closures_(1) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001855
1856 int AddInstruction(LInstruction* instruction, HBasicBlock* block);
1857 LConstantOperand* DefineConstantOperand(HConstant* constant);
1858 Handle<Object> LookupLiteral(LConstantOperand* operand) const;
1859 Representation LookupLiteralRepresentation(LConstantOperand* operand) const;
1860
1861 int GetNextSpillIndex(bool is_double);
1862 LOperand* GetNextSpillSlot(bool is_double);
1863
1864 int ParameterAt(int index);
1865 int GetParameterStackSlot(int index) const;
1866 int spill_slot_count() const { return spill_slot_count_; }
1867 HGraph* graph() const { return graph_; }
1868 const ZoneList<LInstruction*>* instructions() const { return &instructions_; }
1869 void AddGapMove(int index, LOperand* from, LOperand* to);
1870 LGap* GetGapAt(int index) const;
1871 bool IsGapAt(int index) const;
1872 int NearestGapPos(int index) const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001873 void MarkEmptyBlocks();
1874 const ZoneList<LPointerMap*>* pointer_maps() const { return &pointer_maps_; }
1875 LLabel* GetLabel(int block_id) const {
1876 HBasicBlock* block = graph_->blocks()->at(block_id);
1877 int first_instruction = block->first_instruction_index();
1878 return LLabel::cast(instructions_[first_instruction]);
1879 }
1880 int LookupDestination(int block_id) const {
1881 LLabel* cur = GetLabel(block_id);
1882 while (cur->replacement() != NULL) {
1883 cur = cur->replacement();
1884 }
1885 return cur->block_id();
1886 }
1887 Label* GetAssemblyLabel(int block_id) const {
1888 LLabel* label = GetLabel(block_id);
1889 ASSERT(!label->HasReplacement());
1890 return label->label();
1891 }
1892
1893 const ZoneList<Handle<JSFunction> >* inlined_closures() const {
1894 return &inlined_closures_;
1895 }
1896
1897 void AddInlinedClosure(Handle<JSFunction> closure) {
1898 inlined_closures_.Add(closure);
1899 }
1900
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001901 private:
1902 int spill_slot_count_;
1903 HGraph* const graph_;
1904 ZoneList<LInstruction*> instructions_;
1905 ZoneList<LPointerMap*> pointer_maps_;
1906 ZoneList<Handle<JSFunction> > inlined_closures_;
1907};
1908
1909
1910class LChunkBuilder BASE_EMBEDDED {
1911 public:
1912 LChunkBuilder(HGraph* graph, LAllocator* allocator)
1913 : chunk_(NULL),
1914 graph_(graph),
1915 status_(UNUSED),
1916 current_instruction_(NULL),
1917 current_block_(NULL),
1918 next_block_(NULL),
1919 argument_count_(0),
1920 allocator_(allocator),
1921 position_(RelocInfo::kNoPosition),
1922 instructions_pending_deoptimization_environment_(NULL),
1923 pending_deoptimization_ast_id_(AstNode::kNoNumber) { }
1924
1925 // Build the sequence for the graph.
1926 LChunk* Build();
1927
1928 // Declare methods that deal with the individual node types.
1929#define DECLARE_DO(type) LInstruction* Do##type(H##type* node);
1930 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_DO)
1931#undef DECLARE_DO
1932
1933 private:
1934 enum Status {
1935 UNUSED,
1936 BUILDING,
1937 DONE,
1938 ABORTED
1939 };
1940
1941 LChunk* chunk() const { return chunk_; }
1942 HGraph* graph() const { return graph_; }
1943
1944 bool is_unused() const { return status_ == UNUSED; }
1945 bool is_building() const { return status_ == BUILDING; }
1946 bool is_done() const { return status_ == DONE; }
1947 bool is_aborted() const { return status_ == ABORTED; }
1948
1949 void Abort(const char* format, ...);
1950
1951 // Methods for getting operands for Use / Define / Temp.
1952 LRegister* ToOperand(Register reg);
1953 LUnallocated* ToUnallocated(Register reg);
1954 LUnallocated* ToUnallocated(XMMRegister reg);
1955
1956 // Methods for setting up define-use relationships.
1957 LOperand* Use(HValue* value, LUnallocated* operand);
1958 LOperand* UseFixed(HValue* value, Register fixed_register);
1959 LOperand* UseFixedDouble(HValue* value, XMMRegister fixed_register);
1960
1961 // A value that is guaranteed to be allocated to a register.
1962 // Operand created by UseRegister is guaranteed to be live until the end of
1963 // instruction. This means that register allocator will not reuse it's
1964 // register for any other operand inside instruction.
1965 // Operand created by UseRegisterAtStart is guaranteed to be live only at
1966 // instruction start. Register allocator is free to assign the same register
1967 // to some other operand used inside instruction (i.e. temporary or
1968 // output).
1969 LOperand* UseRegister(HValue* value);
1970 LOperand* UseRegisterAtStart(HValue* value);
1971
1972 // A value in a register that may be trashed.
1973 LOperand* UseTempRegister(HValue* value);
1974 LOperand* Use(HValue* value);
1975 LOperand* UseAtStart(HValue* value);
1976 LOperand* UseOrConstant(HValue* value);
1977 LOperand* UseOrConstantAtStart(HValue* value);
1978 LOperand* UseRegisterOrConstant(HValue* value);
1979 LOperand* UseRegisterOrConstantAtStart(HValue* value);
1980
1981 // Methods for setting up define-use relationships.
1982 // Return the same instruction that they are passed.
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001983 template<int I, int T>
1984 LInstruction* Define(LTemplateInstruction<1, I, T>* instr,
1985 LUnallocated* result);
1986 template<int I, int T>
1987 LInstruction* Define(LTemplateInstruction<1, I, T>* instr);
1988 template<int I, int T>
1989 LInstruction* DefineAsRegister(LTemplateInstruction<1, I, T>* instr);
1990 template<int I, int T>
1991 LInstruction* DefineAsSpilled(LTemplateInstruction<1, I, T>* instr,
1992 int index);
1993 template<int I, int T>
1994 LInstruction* DefineSameAsFirst(LTemplateInstruction<1, I, T>* instr);
1995 template<int I, int T>
1996 LInstruction* DefineFixed(LTemplateInstruction<1, I, T>* instr,
1997 Register reg);
1998 template<int I, int T>
1999 LInstruction* DefineFixedDouble(LTemplateInstruction<1, I, T>* instr,
2000 XMMRegister reg);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002001 LInstruction* AssignEnvironment(LInstruction* instr);
2002 LInstruction* AssignPointerMap(LInstruction* instr);
2003
2004 enum CanDeoptimize { CAN_DEOPTIMIZE_EAGERLY, CANNOT_DEOPTIMIZE_EAGERLY };
2005
2006 // By default we assume that instruction sequences generated for calls
2007 // cannot deoptimize eagerly and we do not attach environment to this
2008 // instruction.
2009 LInstruction* MarkAsCall(
2010 LInstruction* instr,
2011 HInstruction* hinstr,
2012 CanDeoptimize can_deoptimize = CANNOT_DEOPTIMIZE_EAGERLY);
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002013 LInstruction* MarkAsSaveDoubles(LInstruction* instr);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002014
2015 LInstruction* SetInstructionPendingDeoptimizationEnvironment(
2016 LInstruction* instr, int ast_id);
2017 void ClearInstructionPendingDeoptimizationEnvironment();
2018
2019 LEnvironment* CreateEnvironment(HEnvironment* hydrogen_env);
2020
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002021 // Temporary operand that must be in a register.
2022 LUnallocated* TempRegister();
2023 LOperand* FixedTemp(Register reg);
2024 LOperand* FixedTemp(XMMRegister reg);
2025
2026 void VisitInstruction(HInstruction* current);
2027
2028 void DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block);
2029 LInstruction* DoBit(Token::Value op, HBitwiseBinaryOperation* instr);
2030 LInstruction* DoShift(Token::Value op, HBitwiseBinaryOperation* instr);
2031 LInstruction* DoArithmeticD(Token::Value op,
2032 HArithmeticBinaryOperation* instr);
2033 LInstruction* DoArithmeticT(Token::Value op,
2034 HArithmeticBinaryOperation* instr);
2035
2036 LChunk* chunk_;
2037 HGraph* const graph_;
2038 Status status_;
2039 HInstruction* current_instruction_;
2040 HBasicBlock* current_block_;
2041 HBasicBlock* next_block_;
2042 int argument_count_;
2043 LAllocator* allocator_;
2044 int position_;
2045 LInstruction* instructions_pending_deoptimization_environment_;
2046 int pending_deoptimization_ast_id_;
2047
2048 DISALLOW_COPY_AND_ASSIGN(LChunkBuilder);
2049};
2050
2051#undef DECLARE_HYDROGEN_ACCESSOR
2052#undef DECLARE_INSTRUCTION
2053#undef DECLARE_CONCRETE_INSTRUCTION
2054
2055} } // namespace v8::internal
2056
2057#endif // V8_IA32_LITHIUM_IA32_H_