blob: 1cdd31ede883dcf08c4ab8a3327c3ba2a05cbd96 [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
erik.corry@gmail.com0511e242011-01-19 11:11:08 +000046// LTemplateInstruction
47// LControlInstruction
48// LBranch
49// LClassOfTestAndBranch
50// LCmpJSObjectEqAndBranch
51// LCmpIDAndBranch
52// LHasCachedArrayIndexAndBranch
53// LHasInstanceTypeAndBranch
54// LInstanceOfAndBranch
55// LIsNullAndBranch
56// LIsObjectAndBranch
57// LIsSmiAndBranch
58// LTypeofIsAndBranch
59// LAccessArgumentsAt
60// LArgumentsElements
61// LArgumentsLength
kasperl@chromium.orga5551262010-12-07 12:49:48 +000062// LAddI
63// LApplyArguments
64// LArithmeticD
65// LArithmeticT
66// LBitI
67// LBoundsCheck
68// LCmpID
kasperl@chromium.orga5551262010-12-07 12:49:48 +000069// LCmpJSObjectEq
kasperl@chromium.orga5551262010-12-07 12:49:48 +000070// LCmpT
71// LDivI
72// LInstanceOf
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +000073// LInstanceOfKnownGlobal
kasperl@chromium.orga5551262010-12-07 12:49:48 +000074// LLoadKeyedFastElement
75// LLoadKeyedGeneric
76// LModI
77// LMulI
ager@chromium.org5f0c45f2010-12-17 08:51:21 +000078// LPower
kasperl@chromium.orga5551262010-12-07 12:49:48 +000079// LShiftI
80// LSubI
erik.corry@gmail.com0511e242011-01-19 11:11:08 +000081// LCallConstantFunction
82// LCallFunction
83// LCallGlobal
84// LCallKeyed
85// LCallKnownGlobal
86// LCallNamed
87// LCallRuntime
88// LCallStub
89// LConstant
90// LConstantD
91// LConstantI
92// LConstantT
93// LDeoptimize
94// LFunctionLiteral
95// LGap
96// LLabel
97// LGlobalObject
98// LGlobalReceiver
99// LGoto
100// LLazyBailout
101// LLoadGlobal
102// LCheckPrototypeMaps
103// LLoadContextSlot
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000104// LArrayLiteral
105// LObjectLiteral
106// LRegExpLiteral
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000107// LOsrEntry
108// LParameter
109// LRegExpConstructResult
110// LStackCheck
111// LStoreKeyed
112// LStoreKeyedFastElement
113// LStoreKeyedGeneric
114// LStoreNamed
115// LStoreNamedField
116// LStoreNamedGeneric
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000117// LStringCharCodeAt
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000118// LBitNotI
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000119// LCallNew
120// LCheckFunction
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000121// LCheckPrototypeMaps
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000122// LCheckInstanceType
123// LCheckMap
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000124// LCheckSmi
125// LClassOfTest
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000126// LDeleteProperty
127// LDoubleToI
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000128// LFixedArrayLength
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000129// LHasCachedArrayIndex
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000130// LHasInstanceType
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000131// LInteger32ToDouble
132// LIsNull
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000133// LIsObject
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000134// LIsSmi
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000135// LJSArrayLength
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000136// LLoadNamedField
137// LLoadNamedGeneric
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000138// LLoadFunctionPrototype
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000139// LNumberTagD
140// LNumberTagI
141// LPushArgument
142// LReturn
143// LSmiTag
144// LStoreGlobal
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000145// LStringLength
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000146// LTaggedToI
147// LThrow
148// LTypeof
149// LTypeofIs
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000150// LUnaryMathOperation
151// LValueOf
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000152// LUnknownOSRValue
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000153
154#define LITHIUM_ALL_INSTRUCTION_LIST(V) \
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000155 V(ControlInstruction) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000156 V(Constant) \
157 V(Call) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000158 V(StoreKeyed) \
159 V(StoreNamed) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000160 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) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000258 V(StringCharCodeAt) \
259 V(StringLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000260 V(SubI) \
261 V(TaggedToI) \
262 V(Throw) \
263 V(Typeof) \
264 V(TypeofIs) \
265 V(TypeofIsAndBranch) \
266 V(UnaryMathOperation) \
267 V(UnknownOSRValue) \
268 V(ValueOf)
269
270
271#define DECLARE_INSTRUCTION(type) \
272 virtual bool Is##type() const { return true; } \
273 static L##type* cast(LInstruction* instr) { \
274 ASSERT(instr->Is##type()); \
275 return reinterpret_cast<L##type*>(instr); \
276 }
277
278
279#define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic) \
280 virtual void CompileToNative(LCodeGen* generator); \
281 virtual const char* Mnemonic() const { return mnemonic; } \
282 DECLARE_INSTRUCTION(type)
283
284
285#define DECLARE_HYDROGEN_ACCESSOR(type) \
286 H##type* hydrogen() const { \
287 return H##type::cast(hydrogen_value()); \
288 }
289
290
291class LInstruction: public ZoneObject {
292 public:
293 LInstruction()
294 : hydrogen_value_(NULL) { }
295 virtual ~LInstruction() { }
296
297 virtual void CompileToNative(LCodeGen* generator) = 0;
298 virtual const char* Mnemonic() const = 0;
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000299 virtual void PrintTo(StringStream* stream);
300 virtual void PrintDataTo(StringStream* stream) = 0;
301 virtual void PrintOutputOperandTo(StringStream* stream) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000302
303 // Declare virtual type testers.
304#define DECLARE_DO(type) virtual bool Is##type() const { return false; }
305 LITHIUM_ALL_INSTRUCTION_LIST(DECLARE_DO)
306#undef DECLARE_DO
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000307
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000308 virtual bool IsControl() const { return false; }
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000309 virtual void SetBranchTargets(int true_block_id, int false_block_id) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000310
311 void set_environment(LEnvironment* env) { environment_.set(env); }
312 LEnvironment* environment() const { return environment_.get(); }
313 bool HasEnvironment() const { return environment_.is_set(); }
314
315 void set_pointer_map(LPointerMap* p) { pointer_map_.set(p); }
316 LPointerMap* pointer_map() const { return pointer_map_.get(); }
317 bool HasPointerMap() const { return pointer_map_.is_set(); }
318
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000319 virtual bool HasResult() const = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000320
321 void set_hydrogen_value(HValue* value) { hydrogen_value_ = value; }
322 HValue* hydrogen_value() const { return hydrogen_value_; }
323
324 void set_deoptimization_environment(LEnvironment* env) {
325 deoptimization_environment_.set(env);
326 }
327 LEnvironment* deoptimization_environment() const {
328 return deoptimization_environment_.get();
329 }
330 bool HasDeoptimizationEnvironment() const {
331 return deoptimization_environment_.is_set();
332 }
333
334 private:
335 SetOncePointer<LEnvironment> environment_;
336 SetOncePointer<LPointerMap> pointer_map_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000337 HValue* hydrogen_value_;
338 SetOncePointer<LEnvironment> deoptimization_environment_;
339};
340
341
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000342template<typename ElementType, int NumElements>
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000343class OperandContainer {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000344 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000345 OperandContainer() {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000346 for (int i = 0; i < NumElements; i++) elems_[i] = NULL;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000347 }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000348 int length() { return NumElements; }
349 ElementType& operator[](int i) {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000350 ASSERT(i < length());
351 return elems_[i];
352 }
353 void PrintOperandsTo(StringStream* stream);
354
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000355 private:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000356 ElementType elems_[NumElements];
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000357};
358
359
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000360template<typename ElementType>
361class OperandContainer<ElementType, 0> {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000362 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000363 int length() { return 0; }
364 void PrintOperandsTo(StringStream* stream) { }
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000365};
366
367
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000368// R = number of result operands (0 or 1).
369// I = number of input operands.
370// T = number of temporary operands.
371template<int R, int I, int T>
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000372class LTemplateInstruction: public LInstruction {
373 public:
374 // Allow 0 or 1 output operands.
375 STATIC_ASSERT(R == 0 || R == 1);
376 virtual bool HasResult() const { return R != 0; }
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000377 void set_result(LOperand* operand) { results_[0] = operand; }
378 LOperand* result() { return results_[0]; }
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000379
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000380 int InputCount() { return I; }
381 LOperand* InputAt(int i) { return inputs_[i]; }
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000382
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000383 int TempCount() { return T; }
384 LOperand* TempAt(int i) { return temps_[i]; }
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000385
386 virtual void PrintDataTo(StringStream* stream);
387 virtual void PrintOutputOperandTo(StringStream* stream);
388
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000389 protected:
390 OperandContainer<LOperand*, R> results_;
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000391 OperandContainer<LOperand*, I> inputs_;
392 OperandContainer<LOperand*, T> temps_;
393};
394
395
396class LGap: public LTemplateInstruction<0, 0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000397 public:
398 explicit LGap(HBasicBlock* block)
399 : block_(block) {
400 parallel_moves_[BEFORE] = NULL;
401 parallel_moves_[START] = NULL;
402 parallel_moves_[END] = NULL;
403 parallel_moves_[AFTER] = NULL;
404 }
405
406 DECLARE_CONCRETE_INSTRUCTION(Gap, "gap")
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000407 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000408
409 bool IsRedundant() const;
410
411 HBasicBlock* block() const { return block_; }
412
413 enum InnerPosition {
414 BEFORE,
415 START,
416 END,
417 AFTER,
418 FIRST_INNER_POSITION = BEFORE,
419 LAST_INNER_POSITION = AFTER
420 };
421
422 LParallelMove* GetOrCreateParallelMove(InnerPosition pos) {
423 if (parallel_moves_[pos] == NULL) parallel_moves_[pos] = new LParallelMove;
424 return parallel_moves_[pos];
425 }
426
427 LParallelMove* GetParallelMove(InnerPosition pos) {
428 return parallel_moves_[pos];
429 }
430
431 private:
432 LParallelMove* parallel_moves_[LAST_INNER_POSITION + 1];
433 HBasicBlock* block_;
434};
435
436
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000437class LGoto: public LTemplateInstruction<0, 0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000438 public:
439 LGoto(int block_id, bool include_stack_check = false)
440 : block_id_(block_id), include_stack_check_(include_stack_check) { }
441
442 DECLARE_CONCRETE_INSTRUCTION(Goto, "goto")
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000443 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000444 virtual bool IsControl() const { return true; }
445
446 int block_id() const { return block_id_; }
447 bool include_stack_check() const { return include_stack_check_; }
448
449 private:
450 int block_id_;
451 bool include_stack_check_;
452};
453
454
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000455class LLazyBailout: public LTemplateInstruction<0, 0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000456 public:
457 LLazyBailout() : gap_instructions_size_(0) { }
458
459 DECLARE_CONCRETE_INSTRUCTION(LazyBailout, "lazy-bailout")
460
461 void set_gap_instructions_size(int gap_instructions_size) {
462 gap_instructions_size_ = gap_instructions_size;
463 }
464 int gap_instructions_size() { return gap_instructions_size_; }
465
466 private:
467 int gap_instructions_size_;
468};
469
470
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000471class LDeoptimize: public LTemplateInstruction<0, 0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000472 public:
473 DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize")
474};
475
476
477class LLabel: public LGap {
478 public:
479 explicit LLabel(HBasicBlock* block)
480 : LGap(block), replacement_(NULL) { }
481
482 DECLARE_CONCRETE_INSTRUCTION(Label, "label")
483
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000484 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000485
486 int block_id() const { return block()->block_id(); }
487 bool is_loop_header() const { return block()->IsLoopHeader(); }
488 Label* label() { return &label_; }
489 LLabel* replacement() const { return replacement_; }
490 void set_replacement(LLabel* label) { replacement_ = label; }
491 bool HasReplacement() const { return replacement_ != NULL; }
492
493 private:
494 Label label_;
495 LLabel* replacement_;
496};
497
498
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000499class LParameter: public LTemplateInstruction<1, 0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000500 public:
501 DECLARE_CONCRETE_INSTRUCTION(Parameter, "parameter")
502};
503
504
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000505class LCallStub: public LTemplateInstruction<1, 0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000506 public:
507 DECLARE_CONCRETE_INSTRUCTION(CallStub, "call-stub")
508 DECLARE_HYDROGEN_ACCESSOR(CallStub)
509
510 TranscendentalCache::Type transcendental_type() {
511 return hydrogen()->transcendental_type();
512 }
513};
514
515
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000516class LUnknownOSRValue: public LTemplateInstruction<1, 0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000517 public:
518 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue, "unknown-osr-value")
519};
520
521
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000522template<int I, int T>
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000523class LControlInstruction: public LTemplateInstruction<0, I, T> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000524 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000525 DECLARE_INSTRUCTION(ControlInstruction)
526 virtual bool IsControl() const { return true; }
527
528 int true_block_id() const { return true_block_id_; }
529 int false_block_id() const { return false_block_id_; }
530 void SetBranchTargets(int true_block_id, int false_block_id) {
531 true_block_id_ = true_block_id;
532 false_block_id_ = false_block_id;
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000533 }
534
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000535 private:
536 int true_block_id_;
537 int false_block_id_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000538};
539
540
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000541class LApplyArguments: public LTemplateInstruction<1, 4, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000542 public:
543 LApplyArguments(LOperand* function,
544 LOperand* receiver,
545 LOperand* length,
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000546 LOperand* elements) {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000547 inputs_[0] = function;
548 inputs_[1] = receiver;
549 inputs_[2] = length;
550 inputs_[3] = elements;
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000551 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000552
553 DECLARE_CONCRETE_INSTRUCTION(ApplyArguments, "apply-arguments")
554
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000555 LOperand* function() { return inputs_[0]; }
556 LOperand* receiver() { return inputs_[1]; }
557 LOperand* length() { return inputs_[2]; }
558 LOperand* elements() { return inputs_[3]; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000559};
560
561
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000562class LAccessArgumentsAt: public LTemplateInstruction<1, 3, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000563 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000564 LAccessArgumentsAt(LOperand* arguments, LOperand* length, LOperand* index) {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000565 inputs_[0] = arguments;
566 inputs_[1] = length;
567 inputs_[2] = index;
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000568 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000569
570 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt, "access-arguments-at")
571
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000572 LOperand* arguments() { return inputs_[0]; }
573 LOperand* length() { return inputs_[1]; }
574 LOperand* index() { return inputs_[2]; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000575
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000576 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000577};
578
579
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000580class LArgumentsLength: public LTemplateInstruction<1, 1, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000581 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000582 explicit LArgumentsLength(LOperand* elements) {
583 inputs_[0] = elements;
584 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000585
586 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength, "arguments-length")
587};
588
589
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000590class LArgumentsElements: public LTemplateInstruction<1, 0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000591 public:
592 LArgumentsElements() { }
593
594 DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements, "arguments-elements")
595};
596
597
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000598class LModI: public LTemplateInstruction<1, 2, 1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000599 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000600 LModI(LOperand* left, LOperand* right, LOperand* temp) {
601 inputs_[0] = left;
602 inputs_[1] = right;
603 temps_[0] = temp;
604 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000605
606 DECLARE_CONCRETE_INSTRUCTION(ModI, "mod-i")
607 DECLARE_HYDROGEN_ACCESSOR(Mod)
608};
609
610
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000611class LDivI: public LTemplateInstruction<1, 2, 1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000612 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000613 LDivI(LOperand* left, LOperand* right, LOperand* temp) {
614 inputs_[0] = left;
615 inputs_[1] = right;
616 temps_[0] = temp;
617 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000618
619 DECLARE_CONCRETE_INSTRUCTION(DivI, "div-i")
620 DECLARE_HYDROGEN_ACCESSOR(Div)
621};
622
623
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000624class LMulI: public LTemplateInstruction<1, 2, 1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000625 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000626 LMulI(LOperand* left, LOperand* right, LOperand* temp) {
627 inputs_[0] = left;
628 inputs_[1] = right;
629 temps_[0] = temp;
630 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000631
632 DECLARE_CONCRETE_INSTRUCTION(MulI, "mul-i")
633 DECLARE_HYDROGEN_ACCESSOR(Mul)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000634};
635
636
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000637class LCmpID: public LTemplateInstruction<1, 2, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000638 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000639 LCmpID(LOperand* left, LOperand* right) {
640 inputs_[0] = left;
641 inputs_[1] = right;
642 }
643
644 DECLARE_CONCRETE_INSTRUCTION(CmpID, "cmp-id")
645 DECLARE_HYDROGEN_ACCESSOR(Compare)
646
647 Token::Value op() const { return hydrogen()->token(); }
648 bool is_double() const {
649 return hydrogen()->GetInputRepresentation().IsDouble();
650 }
651};
652
653
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000654class LCmpIDAndBranch: public LControlInstruction<2, 0> {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000655 public:
656 LCmpIDAndBranch(LOperand* left, LOperand* right) {
657 inputs_[0] = left;
658 inputs_[1] = right;
659 }
660
661 DECLARE_CONCRETE_INSTRUCTION(CmpIDAndBranch, "cmp-id-and-branch")
662 DECLARE_HYDROGEN_ACCESSOR(Compare)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000663
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000664 Token::Value op() const { return hydrogen()->token(); }
665 bool is_double() const {
666 return hydrogen()->GetInputRepresentation().IsDouble();
667 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000668
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000669 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000670};
671
672
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000673class LUnaryMathOperation: public LTemplateInstruction<1, 1, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000674 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000675 explicit LUnaryMathOperation(LOperand* value) {
676 inputs_[0] = value;
677 }
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
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000687class LCmpJSObjectEq: public LTemplateInstruction<1, 2, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000688 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000689 LCmpJSObjectEq(LOperand* left, LOperand* right) {
690 inputs_[0] = left;
691 inputs_[1] = right;
692 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000693
694 DECLARE_CONCRETE_INSTRUCTION(CmpJSObjectEq, "cmp-jsobject-eq")
695};
696
697
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000698class LCmpJSObjectEqAndBranch: public LControlInstruction<2, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000699 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000700 LCmpJSObjectEqAndBranch(LOperand* left, LOperand* right) {
701 inputs_[0] = left;
702 inputs_[1] = right;
703 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000704
705 DECLARE_CONCRETE_INSTRUCTION(CmpJSObjectEqAndBranch,
706 "cmp-jsobject-eq-and-branch")
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000707};
708
709
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000710class LIsNull: public LTemplateInstruction<1, 1, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000711 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000712 explicit LIsNull(LOperand* value) {
713 inputs_[0] = value;
714 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000715
716 DECLARE_CONCRETE_INSTRUCTION(IsNull, "is-null")
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000717 DECLARE_HYDROGEN_ACCESSOR(IsNull)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000718
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000719 bool is_strict() const { return hydrogen()->is_strict(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000720};
721
722
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000723class LIsNullAndBranch: public LControlInstruction<1, 1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000724 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000725 LIsNullAndBranch(LOperand* value, LOperand* temp) {
726 inputs_[0] = value;
727 temps_[0] = temp;
728 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000729
730 DECLARE_CONCRETE_INSTRUCTION(IsNullAndBranch, "is-null-and-branch")
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000731 DECLARE_HYDROGEN_ACCESSOR(IsNull)
732
733 bool is_strict() const { return hydrogen()->is_strict(); }
734
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000735 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000736};
737
738
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000739class LIsObject: public LTemplateInstruction<1, 1, 1> {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000740 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000741 LIsObject(LOperand* value, LOperand* temp) {
742 inputs_[0] = value;
743 temps_[0] = temp;
744 }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000745
746 DECLARE_CONCRETE_INSTRUCTION(IsObject, "is-object")
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000747};
748
749
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000750class LIsObjectAndBranch: public LControlInstruction<1, 2> {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000751 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000752 LIsObjectAndBranch(LOperand* value, LOperand* temp, LOperand* temp2) {
753 inputs_[0] = value;
754 temps_[0] = temp;
755 temps_[1] = temp2;
756 }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000757
758 DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch, "is-object-and-branch")
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000759
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000760 virtual void PrintDataTo(StringStream* stream);
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000761};
762
763
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000764class LIsSmi: public LTemplateInstruction<1, 1, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000765 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000766 explicit LIsSmi(LOperand* value) {
767 inputs_[0] = value;
768 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000769
770 DECLARE_CONCRETE_INSTRUCTION(IsSmi, "is-smi")
771 DECLARE_HYDROGEN_ACCESSOR(IsSmi)
772};
773
774
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000775class LIsSmiAndBranch: public LControlInstruction<1, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000776 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000777 explicit LIsSmiAndBranch(LOperand* value) {
778 inputs_[0] = value;
779 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000780
781 DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch, "is-smi-and-branch")
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000782
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000783 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000784};
785
786
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000787class LHasInstanceType: public LTemplateInstruction<1, 1, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000788 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000789 explicit LHasInstanceType(LOperand* value) {
790 inputs_[0] = value;
791 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000792
793 DECLARE_CONCRETE_INSTRUCTION(HasInstanceType, "has-instance-type")
794 DECLARE_HYDROGEN_ACCESSOR(HasInstanceType)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000795};
796
797
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000798class LHasInstanceTypeAndBranch: public LControlInstruction<1, 1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000799 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000800 LHasInstanceTypeAndBranch(LOperand* value, LOperand* temp) {
801 inputs_[0] = value;
802 temps_[0] = temp;
803 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000804
805 DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch,
806 "has-instance-type-and-branch")
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000807 DECLARE_HYDROGEN_ACCESSOR(HasInstanceType)
808
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000809 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000810};
811
812
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000813class LHasCachedArrayIndex: public LTemplateInstruction<1, 1, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000814 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000815 explicit LHasCachedArrayIndex(LOperand* value) {
816 inputs_[0] = value;
817 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000818
819 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndex, "has-cached-array-index")
820 DECLARE_HYDROGEN_ACCESSOR(HasCachedArrayIndex)
821};
822
823
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000824class LHasCachedArrayIndexAndBranch: public LControlInstruction<1, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000825 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000826 explicit LHasCachedArrayIndexAndBranch(LOperand* value) {
827 inputs_[0] = value;
828 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000829
830 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndexAndBranch,
831 "has-cached-array-index-and-branch")
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000832 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000833};
834
835
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000836class LClassOfTest: public LTemplateInstruction<1, 1, 1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000837 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000838 LClassOfTest(LOperand* value, LOperand* temp) {
839 inputs_[0] = value;
840 temps_[0] = temp;
841 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000842
843 DECLARE_CONCRETE_INSTRUCTION(ClassOfTest, "class-of-test")
844 DECLARE_HYDROGEN_ACCESSOR(ClassOfTest)
845
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000846 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000847};
848
849
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000850class LClassOfTestAndBranch: public LControlInstruction<1, 2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000851 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000852 LClassOfTestAndBranch(LOperand* value, LOperand* temp, LOperand* temp2) {
853 inputs_[0] = value;
854 temps_[0] = temp;
855 temps_[1] = temp2;
856 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000857
858 DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch,
859 "class-of-test-and-branch")
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000860 DECLARE_HYDROGEN_ACCESSOR(ClassOfTest)
861
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000862 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000863};
864
865
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000866class LCmpT: public LTemplateInstruction<1, 2, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000867 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000868 LCmpT(LOperand* left, LOperand* right) {
869 inputs_[0] = left;
870 inputs_[1] = right;
871 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000872
873 DECLARE_CONCRETE_INSTRUCTION(CmpT, "cmp-t")
874 DECLARE_HYDROGEN_ACCESSOR(Compare)
875
876 Token::Value op() const { return hydrogen()->token(); }
877};
878
879
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000880class LCmpTAndBranch: public LControlInstruction<2, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000881 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000882 LCmpTAndBranch(LOperand* left, LOperand* right) {
883 inputs_[0] = left;
884 inputs_[1] = right;
885 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000886
887 DECLARE_CONCRETE_INSTRUCTION(CmpTAndBranch, "cmp-t-and-branch")
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000888 DECLARE_HYDROGEN_ACCESSOR(Compare)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000889
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000890 Token::Value op() const { return hydrogen()->token(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000891};
892
893
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000894class LInstanceOf: public LTemplateInstruction<1, 2, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000895 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000896 LInstanceOf(LOperand* left, LOperand* right) {
897 inputs_[0] = left;
898 inputs_[1] = right;
899 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000900
901 DECLARE_CONCRETE_INSTRUCTION(InstanceOf, "instance-of")
902};
903
904
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000905class LInstanceOfAndBranch: public LControlInstruction<2, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000906 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000907 LInstanceOfAndBranch(LOperand* left, LOperand* right) {
908 inputs_[0] = left;
909 inputs_[1] = right;
910 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000911
912 DECLARE_CONCRETE_INSTRUCTION(InstanceOfAndBranch, "instance-of-and-branch")
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000913};
914
915
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000916class LInstanceOfKnownGlobal: public LTemplateInstruction<1, 1, 1> {
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000917 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000918 LInstanceOfKnownGlobal(LOperand* value, LOperand* temp) {
919 inputs_[0] = value;
920 temps_[0] = temp;
921 }
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000922
923 DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal,
924 "instance-of-known-global")
925 DECLARE_HYDROGEN_ACCESSOR(InstanceOfKnownGlobal)
926
927 Handle<JSFunction> function() const { return hydrogen()->function(); }
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000928};
929
930
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000931class LBoundsCheck: public LTemplateInstruction<0, 2, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000932 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000933 LBoundsCheck(LOperand* index, LOperand* length) {
934 inputs_[0] = index;
935 inputs_[1] = length;
936 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000937
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000938 LOperand* index() { return inputs_[0]; }
939 LOperand* length() { return inputs_[1]; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000940
941 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck, "bounds-check")
942};
943
944
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000945class LBitI: public LTemplateInstruction<1, 2, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000946 public:
947 LBitI(Token::Value op, LOperand* left, LOperand* right)
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000948 : op_(op) {
949 inputs_[0] = left;
950 inputs_[1] = right;
951 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000952
953 Token::Value op() const { return op_; }
954
955 DECLARE_CONCRETE_INSTRUCTION(BitI, "bit-i")
956
957 private:
958 Token::Value op_;
959};
960
961
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000962class LShiftI: public LTemplateInstruction<1, 2, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000963 public:
964 LShiftI(Token::Value op, LOperand* left, LOperand* right, bool can_deopt)
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000965 : op_(op), can_deopt_(can_deopt) {
966 inputs_[0] = left;
967 inputs_[1] = right;
968 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000969
970 Token::Value op() const { return op_; }
971
972 bool can_deopt() const { return can_deopt_; }
973
974 DECLARE_CONCRETE_INSTRUCTION(ShiftI, "shift-i")
975
976 private:
977 Token::Value op_;
978 bool can_deopt_;
979};
980
981
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000982class LSubI: public LTemplateInstruction<1, 2, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000983 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000984 LSubI(LOperand* left, LOperand* right) {
985 inputs_[0] = left;
986 inputs_[1] = right;
987 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000988
989 DECLARE_CONCRETE_INSTRUCTION(SubI, "sub-i")
990 DECLARE_HYDROGEN_ACCESSOR(Sub)
991};
992
993
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000994class LConstant: public LTemplateInstruction<1, 0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000995 DECLARE_INSTRUCTION(Constant)
996};
997
998
999class LConstantI: public LConstant {
1000 public:
1001 explicit LConstantI(int32_t value) : value_(value) { }
1002 int32_t value() const { return value_; }
1003
1004 DECLARE_CONCRETE_INSTRUCTION(ConstantI, "constant-i")
1005
1006 private:
1007 int32_t value_;
1008};
1009
1010
1011class LConstantD: public LConstant {
1012 public:
1013 explicit LConstantD(double value) : value_(value) { }
1014 double value() const { return value_; }
1015
1016 DECLARE_CONCRETE_INSTRUCTION(ConstantD, "constant-d")
1017
1018 private:
1019 double value_;
1020};
1021
1022
1023class LConstantT: public LConstant {
1024 public:
1025 explicit LConstantT(Handle<Object> value) : value_(value) { }
1026 Handle<Object> value() const { return value_; }
1027
1028 DECLARE_CONCRETE_INSTRUCTION(ConstantT, "constant-t")
1029
1030 private:
1031 Handle<Object> value_;
1032};
1033
1034
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001035class LBranch: public LControlInstruction<1, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001036 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001037 explicit LBranch(LOperand* value) {
1038 inputs_[0] = value;
1039 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001040
1041 DECLARE_CONCRETE_INSTRUCTION(Branch, "branch")
1042 DECLARE_HYDROGEN_ACCESSOR(Value)
1043
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001044 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001045};
1046
1047
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001048class LCmpMapAndBranch: public LTemplateInstruction<0, 1, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001049 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001050 explicit LCmpMapAndBranch(LOperand* value) {
1051 inputs_[0] = value;
1052 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001053
1054 DECLARE_CONCRETE_INSTRUCTION(CmpMapAndBranch, "cmp-map-and-branch")
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001055 DECLARE_HYDROGEN_ACCESSOR(CompareMap)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001056
1057 virtual bool IsControl() const { return true; }
1058
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00001059 Handle<Map> map() const { return hydrogen()->map(); }
1060 int true_block_id() const {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001061 return hydrogen()->FirstSuccessor()->block_id();
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00001062 }
1063 int false_block_id() const {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001064 return hydrogen()->SecondSuccessor()->block_id();
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00001065 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001066};
1067
1068
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001069class LJSArrayLength: public LTemplateInstruction<1, 1, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001070 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001071 explicit LJSArrayLength(LOperand* value) {
1072 inputs_[0] = value;
1073 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001074
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001075 DECLARE_CONCRETE_INSTRUCTION(JSArrayLength, "js-array-length")
1076 DECLARE_HYDROGEN_ACCESSOR(JSArrayLength)
1077};
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001078
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001079
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001080class LFixedArrayLength: public LTemplateInstruction<1, 1, 0> {
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001081 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001082 explicit LFixedArrayLength(LOperand* value) {
1083 inputs_[0] = value;
1084 }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001085
1086 DECLARE_CONCRETE_INSTRUCTION(FixedArrayLength, "fixed-array-length")
1087 DECLARE_HYDROGEN_ACCESSOR(FixedArrayLength)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001088};
1089
1090
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001091class LValueOf: public LTemplateInstruction<1, 1, 1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001092 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001093 LValueOf(LOperand* value, LOperand* temp) {
1094 inputs_[0] = value;
1095 temps_[0] = temp;
1096 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001097
1098 DECLARE_CONCRETE_INSTRUCTION(ValueOf, "value-of")
1099 DECLARE_HYDROGEN_ACCESSOR(ValueOf)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001100};
1101
1102
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001103class LThrow: public LTemplateInstruction<0, 1, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001104 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001105 explicit LThrow(LOperand* value) {
1106 inputs_[0] = value;
1107 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001108
1109 DECLARE_CONCRETE_INSTRUCTION(Throw, "throw")
1110};
1111
1112
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001113class LBitNotI: public LTemplateInstruction<1, 1, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001114 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001115 explicit LBitNotI(LOperand* value) {
1116 inputs_[0] = value;
1117 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001118
1119 DECLARE_CONCRETE_INSTRUCTION(BitNotI, "bit-not-i")
1120};
1121
1122
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001123class LAddI: public LTemplateInstruction<1, 2, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001124 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001125 LAddI(LOperand* left, LOperand* right) {
1126 inputs_[0] = left;
1127 inputs_[1] = right;
1128 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001129
1130 DECLARE_CONCRETE_INSTRUCTION(AddI, "add-i")
1131 DECLARE_HYDROGEN_ACCESSOR(Add)
1132};
1133
1134
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001135class LPower: public LTemplateInstruction<1, 2, 0> {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001136 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001137 LPower(LOperand* left, LOperand* right) {
1138 inputs_[0] = left;
1139 inputs_[1] = right;
1140 }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001141
1142 DECLARE_CONCRETE_INSTRUCTION(Power, "power")
1143 DECLARE_HYDROGEN_ACCESSOR(Power)
1144};
1145
1146
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001147class LArithmeticD: public LTemplateInstruction<1, 2, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001148 public:
1149 LArithmeticD(Token::Value op, LOperand* left, LOperand* right)
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001150 : op_(op) {
1151 inputs_[0] = left;
1152 inputs_[1] = right;
1153 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001154
1155 Token::Value op() const { return op_; }
1156
1157 virtual void CompileToNative(LCodeGen* generator);
1158 virtual const char* Mnemonic() const;
1159
1160 private:
1161 Token::Value op_;
1162};
1163
1164
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001165class LArithmeticT: public LTemplateInstruction<1, 2, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001166 public:
1167 LArithmeticT(Token::Value op, LOperand* left, LOperand* right)
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001168 : op_(op) {
1169 inputs_[0] = left;
1170 inputs_[1] = right;
1171 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001172
1173 virtual void CompileToNative(LCodeGen* generator);
1174 virtual const char* Mnemonic() const;
1175
1176 Token::Value op() const { return op_; }
1177
1178 private:
1179 Token::Value op_;
1180};
1181
1182
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001183class LReturn: public LTemplateInstruction<0, 1, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001184 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001185 explicit LReturn(LOperand* value) {
1186 inputs_[0] = value;
1187 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001188
1189 DECLARE_CONCRETE_INSTRUCTION(Return, "return")
1190};
1191
1192
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001193class LLoadNamedField: public LTemplateInstruction<1, 1, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001194 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001195 explicit LLoadNamedField(LOperand* object) {
1196 inputs_[0] = object;
1197 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001198
1199 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load-named-field")
1200 DECLARE_HYDROGEN_ACCESSOR(LoadNamedField)
1201};
1202
1203
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001204class LLoadNamedGeneric: public LTemplateInstruction<1, 1, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001205 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001206 explicit LLoadNamedGeneric(LOperand* object) {
1207 inputs_[0] = object;
1208 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001209
1210 DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric, "load-named-generic")
1211 DECLARE_HYDROGEN_ACCESSOR(LoadNamedGeneric)
1212
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001213 LOperand* object() { return inputs_[0]; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001214 Handle<Object> name() const { return hydrogen()->name(); }
1215};
1216
1217
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001218class LLoadFunctionPrototype: public LTemplateInstruction<1, 1, 1> {
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001219 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001220 LLoadFunctionPrototype(LOperand* function, LOperand* temp) {
1221 inputs_[0] = function;
1222 temps_[0] = temp;
1223 }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001224
1225 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype, "load-function-prototype")
1226 DECLARE_HYDROGEN_ACCESSOR(LoadFunctionPrototype)
1227
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001228 LOperand* function() { return inputs_[0]; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001229};
1230
1231
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001232class LLoadElements: public LTemplateInstruction<1, 1, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001233 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001234 explicit LLoadElements(LOperand* object) {
1235 inputs_[0] = object;
1236 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001237
1238 DECLARE_CONCRETE_INSTRUCTION(LoadElements, "load-elements")
1239};
1240
1241
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001242class LLoadKeyedFastElement: public LTemplateInstruction<1, 2, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001243 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001244 LLoadKeyedFastElement(LOperand* elements, LOperand* key) {
1245 inputs_[0] = elements;
1246 inputs_[1] = key;
1247 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001248
1249 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement, "load-keyed-fast-element")
1250 DECLARE_HYDROGEN_ACCESSOR(LoadKeyedFastElement)
1251
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001252 LOperand* elements() { return inputs_[0]; }
1253 LOperand* key() { return inputs_[1]; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001254};
1255
1256
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001257class LLoadKeyedGeneric: public LTemplateInstruction<1, 2, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001258 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001259 LLoadKeyedGeneric(LOperand* obj, LOperand* key) {
1260 inputs_[0] = obj;
1261 inputs_[1] = key;
1262 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001263
1264 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric, "load-keyed-generic")
1265
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001266 LOperand* object() { return inputs_[0]; }
1267 LOperand* key() { return inputs_[1]; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001268};
1269
1270
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001271class LLoadGlobal: public LTemplateInstruction<1, 0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001272 public:
1273 DECLARE_CONCRETE_INSTRUCTION(LoadGlobal, "load-global")
1274 DECLARE_HYDROGEN_ACCESSOR(LoadGlobal)
1275};
1276
1277
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001278class LStoreGlobal: public LTemplateInstruction<0, 1, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001279 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001280 explicit LStoreGlobal(LOperand* value) {
1281 inputs_[0] = value;
1282 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001283
1284 DECLARE_CONCRETE_INSTRUCTION(StoreGlobal, "store-global")
1285 DECLARE_HYDROGEN_ACCESSOR(StoreGlobal)
1286};
1287
1288
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001289class LLoadContextSlot: public LTemplateInstruction<1, 0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001290 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001291 DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot, "load-context-slot")
1292 DECLARE_HYDROGEN_ACCESSOR(LoadContextSlot)
1293
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001294 int context_chain_length() { return hydrogen()->context_chain_length(); }
1295 int slot_index() { return hydrogen()->slot_index(); }
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001296
1297 virtual void PrintDataTo(StringStream* stream);
1298};
1299
1300
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001301class LPushArgument: public LTemplateInstruction<0, 1, 0> {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001302 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001303 explicit LPushArgument(LOperand* value) {
1304 inputs_[0] = value;
1305 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001306
1307 DECLARE_CONCRETE_INSTRUCTION(PushArgument, "push-argument")
1308};
1309
1310
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001311class LGlobalObject: public LTemplateInstruction<1, 0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001312 public:
1313 DECLARE_CONCRETE_INSTRUCTION(GlobalObject, "global-object")
1314};
1315
1316
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001317class LGlobalReceiver: public LTemplateInstruction<1, 0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001318 public:
1319 DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver, "global-receiver")
1320};
1321
1322
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001323class LCallConstantFunction: public LTemplateInstruction<1, 0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001324 public:
1325 DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction, "call-constant-function")
1326 DECLARE_HYDROGEN_ACCESSOR(CallConstantFunction)
1327
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001328 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001329
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001330 Handle<JSFunction> function() { return hydrogen()->function(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001331 int arity() const { return hydrogen()->argument_count() - 1; }
1332};
1333
1334
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001335class LCallKeyed: public LTemplateInstruction<1, 1, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001336 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001337 explicit LCallKeyed(LOperand* key) {
1338 inputs_[0] = key;
1339 }
1340
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001341 DECLARE_CONCRETE_INSTRUCTION(CallKeyed, "call-keyed")
1342 DECLARE_HYDROGEN_ACCESSOR(CallKeyed)
1343
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001344 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001345
1346 int arity() const { return hydrogen()->argument_count() - 1; }
1347};
1348
1349
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001350class LCallNamed: public LTemplateInstruction<1, 0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001351 public:
1352 DECLARE_CONCRETE_INSTRUCTION(CallNamed, "call-named")
1353 DECLARE_HYDROGEN_ACCESSOR(CallNamed)
1354
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001355 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001356
1357 Handle<String> name() const { return hydrogen()->name(); }
1358 int arity() const { return hydrogen()->argument_count() - 1; }
1359};
1360
1361
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001362class LCallFunction: public LTemplateInstruction<1, 0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001363 public:
1364 DECLARE_CONCRETE_INSTRUCTION(CallFunction, "call-function")
1365 DECLARE_HYDROGEN_ACCESSOR(CallFunction)
1366
1367 int arity() const { return hydrogen()->argument_count() - 2; }
1368};
1369
1370
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001371class LCallGlobal: public LTemplateInstruction<1, 0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001372 public:
1373 DECLARE_CONCRETE_INSTRUCTION(CallGlobal, "call-global")
1374 DECLARE_HYDROGEN_ACCESSOR(CallGlobal)
1375
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001376 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001377
1378 Handle<String> name() const {return hydrogen()->name(); }
1379 int arity() const { return hydrogen()->argument_count() - 1; }
1380};
1381
1382
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001383class LCallKnownGlobal: public LTemplateInstruction<1, 0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001384 public:
1385 DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal, "call-known-global")
1386 DECLARE_HYDROGEN_ACCESSOR(CallKnownGlobal)
1387
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001388 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001389
1390 Handle<JSFunction> target() const { return hydrogen()->target(); }
1391 int arity() const { return hydrogen()->argument_count() - 1; }
1392};
1393
1394
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001395class LCallNew: public LTemplateInstruction<1, 1, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001396 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001397 explicit LCallNew(LOperand* constructor) {
1398 inputs_[0] = constructor;
1399 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001400
1401 DECLARE_CONCRETE_INSTRUCTION(CallNew, "call-new")
1402 DECLARE_HYDROGEN_ACCESSOR(CallNew)
1403
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001404 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001405
1406 int arity() const { return hydrogen()->argument_count() - 1; }
1407};
1408
1409
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001410class LCallRuntime: public LTemplateInstruction<1, 0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001411 public:
1412 DECLARE_CONCRETE_INSTRUCTION(CallRuntime, "call-runtime")
1413 DECLARE_HYDROGEN_ACCESSOR(CallRuntime)
1414
1415 Runtime::Function* function() const { return hydrogen()->function(); }
1416 int arity() const { return hydrogen()->argument_count(); }
1417};
1418
1419
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001420class LInteger32ToDouble: public LTemplateInstruction<1, 1, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001421 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001422 explicit LInteger32ToDouble(LOperand* value) {
1423 inputs_[0] = value;
1424 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001425
1426 DECLARE_CONCRETE_INSTRUCTION(Integer32ToDouble, "int32-to-double")
1427};
1428
1429
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001430class LNumberTagI: public LTemplateInstruction<1, 1, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001431 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001432 explicit LNumberTagI(LOperand* value) {
1433 inputs_[0] = value;
1434 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001435
1436 DECLARE_CONCRETE_INSTRUCTION(NumberTagI, "number-tag-i")
1437};
1438
1439
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001440class LNumberTagD: public LTemplateInstruction<1, 1, 1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001441 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001442 LNumberTagD(LOperand* value, LOperand* temp) {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001443 inputs_[0] = value;
1444 temps_[0] = temp;
1445 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001446
1447 DECLARE_CONCRETE_INSTRUCTION(NumberTagD, "number-tag-d")
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001448};
1449
1450
1451// Sometimes truncating conversion from a tagged value to an int32.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001452class LDoubleToI: public LTemplateInstruction<1, 1, 1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001453 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001454 LDoubleToI(LOperand* value, LOperand* temp) {
1455 inputs_[0] = value;
1456 temps_[0] = temp;
1457 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001458
1459 DECLARE_CONCRETE_INSTRUCTION(DoubleToI, "double-to-i")
1460 DECLARE_HYDROGEN_ACCESSOR(Change)
1461
1462 bool truncating() { return hydrogen()->CanTruncateToInt32(); }
1463};
1464
1465
1466// Truncating conversion from a tagged value to an int32.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001467class LTaggedToI: public LTemplateInstruction<1, 1, 1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001468 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001469 LTaggedToI(LOperand* value, LOperand* temp) {
1470 inputs_[0] = value;
1471 temps_[0] = temp;
1472 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001473
1474 DECLARE_CONCRETE_INSTRUCTION(TaggedToI, "tagged-to-i")
1475 DECLARE_HYDROGEN_ACCESSOR(Change)
1476
1477 bool truncating() { return hydrogen()->CanTruncateToInt32(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001478};
1479
1480
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001481class LSmiTag: public LTemplateInstruction<1, 1, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001482 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001483 explicit LSmiTag(LOperand* value) {
1484 inputs_[0] = value;
1485 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001486
1487 DECLARE_CONCRETE_INSTRUCTION(SmiTag, "smi-tag")
1488};
1489
1490
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001491class LNumberUntagD: public LTemplateInstruction<1, 1, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001492 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001493 explicit LNumberUntagD(LOperand* value) {
1494 inputs_[0] = value;
1495 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001496
1497 DECLARE_CONCRETE_INSTRUCTION(NumberUntagD, "double-untag")
1498};
1499
1500
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001501class LSmiUntag: public LTemplateInstruction<1, 1, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001502 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001503 LSmiUntag(LOperand* value, bool needs_check)
1504 : needs_check_(needs_check) {
1505 inputs_[0] = value;
1506 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001507
1508 DECLARE_CONCRETE_INSTRUCTION(SmiUntag, "smi-untag")
1509
1510 bool needs_check() const { return needs_check_; }
1511
1512 private:
1513 bool needs_check_;
1514};
1515
1516
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001517class LStoreNamed: public LTemplateInstruction<0, 2, 1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001518 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001519 LStoreNamed(LOperand* obj, LOperand* val) {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001520 inputs_[0] = obj;
1521 inputs_[1] = val;
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001522 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001523
1524 DECLARE_INSTRUCTION(StoreNamed)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001525 DECLARE_HYDROGEN_ACCESSOR(StoreNamed)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001526
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001527 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001528
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001529 LOperand* object() { return inputs_[0]; }
1530 LOperand* value() { return inputs_[1]; }
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001531 Handle<Object> name() const { return hydrogen()->name(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001532};
1533
1534
1535class LStoreNamedField: public LStoreNamed {
1536 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001537 LStoreNamedField(LOperand* obj, LOperand* val, LOperand* temp)
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001538 : LStoreNamed(obj, val) {
1539 temps_[0] = temp;
1540 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001541
1542 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store-named-field")
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001543 DECLARE_HYDROGEN_ACCESSOR(StoreNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001544
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001545 bool is_in_object() { return hydrogen()->is_in_object(); }
1546 int offset() { return hydrogen()->offset(); }
1547 bool needs_write_barrier() { return hydrogen()->NeedsWriteBarrier(); }
1548 Handle<Map> transition() const { return hydrogen()->transition(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001549};
1550
1551
1552class LStoreNamedGeneric: public LStoreNamed {
1553 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001554 LStoreNamedGeneric(LOperand* obj, LOperand* val)
1555 : LStoreNamed(obj, val) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001556
1557 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric, "store-named-generic")
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001558 DECLARE_HYDROGEN_ACCESSOR(StoreNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001559};
1560
1561
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001562class LStoreKeyed: public LTemplateInstruction<0, 3, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001563 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001564 LStoreKeyed(LOperand* obj, LOperand* key, LOperand* val) {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001565 inputs_[0] = obj;
1566 inputs_[1] = key;
1567 inputs_[2] = val;
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001568 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001569
1570 DECLARE_INSTRUCTION(StoreKeyed)
1571
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001572 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001573
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001574 LOperand* object() { return inputs_[0]; }
1575 LOperand* key() { return inputs_[1]; }
1576 LOperand* value() { return inputs_[2]; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001577};
1578
1579
1580class LStoreKeyedFastElement: public LStoreKeyed {
1581 public:
1582 LStoreKeyedFastElement(LOperand* obj, LOperand* key, LOperand* val)
1583 : LStoreKeyed(obj, key, val) {}
1584
1585 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement,
1586 "store-keyed-fast-element")
1587 DECLARE_HYDROGEN_ACCESSOR(StoreKeyedFastElement)
1588};
1589
1590
1591class LStoreKeyedGeneric: public LStoreKeyed {
1592 public:
1593 LStoreKeyedGeneric(LOperand* obj, LOperand* key, LOperand* val)
1594 : LStoreKeyed(obj, key, val) { }
1595
1596 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric, "store-keyed-generic")
1597};
1598
1599
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001600class LStringCharCodeAt: public LTemplateInstruction<1, 2, 0> {
1601 public:
1602 LStringCharCodeAt(LOperand* string, LOperand* index) {
1603 inputs_[0] = string;
1604 inputs_[1] = index;
1605 }
1606
1607 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt, "string-char-code-at")
1608 DECLARE_HYDROGEN_ACCESSOR(StringCharCodeAt)
1609
1610 LOperand* string() { return inputs_[0]; }
1611 LOperand* index() { return inputs_[1]; }
1612};
1613
1614
1615class LStringLength: public LTemplateInstruction<1, 1, 0> {
1616 public:
1617 explicit LStringLength(LOperand* string) {
1618 inputs_[0] = string;
1619 }
1620
1621 DECLARE_CONCRETE_INSTRUCTION(StringLength, "string-length")
1622 DECLARE_HYDROGEN_ACCESSOR(StringLength)
1623
1624 LOperand* string() { return inputs_[0]; }
1625};
1626
1627
1628class LCheckFunction: public LTemplateInstruction<0, 1, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001629 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001630 explicit LCheckFunction(LOperand* value) {
1631 inputs_[0] = value;
1632 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001633
1634 DECLARE_CONCRETE_INSTRUCTION(CheckFunction, "check-function")
1635 DECLARE_HYDROGEN_ACCESSOR(CheckFunction)
1636};
1637
1638
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001639class LCheckInstanceType: public LTemplateInstruction<0, 1, 1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001640 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001641 LCheckInstanceType(LOperand* value, LOperand* temp) {
1642 inputs_[0] = value;
1643 temps_[0] = temp;
1644 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001645
1646 DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType, "check-instance-type")
1647 DECLARE_HYDROGEN_ACCESSOR(CheckInstanceType)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001648};
1649
1650
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001651class LCheckMap: public LTemplateInstruction<0, 1, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001652 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001653 explicit LCheckMap(LOperand* value) {
1654 inputs_[0] = value;
1655 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001656
1657 DECLARE_CONCRETE_INSTRUCTION(CheckMap, "check-map")
1658 DECLARE_HYDROGEN_ACCESSOR(CheckMap)
1659};
1660
1661
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001662class LCheckPrototypeMaps: public LTemplateInstruction<0, 0, 1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001663 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001664 explicit LCheckPrototypeMaps(LOperand* temp) {
1665 temps_[0] = temp;
1666 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001667
1668 DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps, "check-prototype-maps")
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001669 DECLARE_HYDROGEN_ACCESSOR(CheckPrototypeMaps)
1670
1671 Handle<JSObject> prototype() const { return hydrogen()->prototype(); }
1672 Handle<JSObject> holder() const { return hydrogen()->holder(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001673};
1674
1675
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001676class LCheckSmi: public LTemplateInstruction<0, 1, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001677 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001678 LCheckSmi(LOperand* value, Condition condition)
1679 : condition_(condition) {
1680 inputs_[0] = value;
1681 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001682
1683 Condition condition() const { return condition_; }
1684
1685 virtual void CompileToNative(LCodeGen* generator);
1686 virtual const char* Mnemonic() const {
1687 return (condition_ == zero) ? "check-non-smi" : "check-smi";
1688 }
1689
1690 private:
1691 Condition condition_;
1692};
1693
1694
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001695class LArrayLiteral: public LTemplateInstruction<1, 0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001696 public:
1697 DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral, "array-literal")
1698 DECLARE_HYDROGEN_ACCESSOR(ArrayLiteral)
1699};
1700
1701
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001702class LObjectLiteral: public LTemplateInstruction<1, 0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001703 public:
1704 DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral, "object-literal")
1705 DECLARE_HYDROGEN_ACCESSOR(ObjectLiteral)
1706};
1707
1708
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001709class LRegExpLiteral: public LTemplateInstruction<1, 0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001710 public:
1711 DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral, "regexp-literal")
1712 DECLARE_HYDROGEN_ACCESSOR(RegExpLiteral)
1713};
1714
1715
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001716class LFunctionLiteral: public LTemplateInstruction<1, 0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001717 public:
1718 DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral, "function-literal")
1719 DECLARE_HYDROGEN_ACCESSOR(FunctionLiteral)
1720
1721 Handle<SharedFunctionInfo> shared_info() { return hydrogen()->shared_info(); }
1722};
1723
1724
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001725class LTypeof: public LTemplateInstruction<1, 1, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001726 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001727 explicit LTypeof(LOperand* value) {
1728 inputs_[0] = value;
1729 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001730
1731 DECLARE_CONCRETE_INSTRUCTION(Typeof, "typeof")
1732};
1733
1734
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001735class LTypeofIs: public LTemplateInstruction<1, 1, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001736 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001737 explicit LTypeofIs(LOperand* value) {
1738 inputs_[0] = value;
1739 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001740
1741 DECLARE_CONCRETE_INSTRUCTION(TypeofIs, "typeof-is")
1742 DECLARE_HYDROGEN_ACCESSOR(TypeofIs)
1743
1744 Handle<String> type_literal() { return hydrogen()->type_literal(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001745
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001746 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001747};
1748
1749
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001750class LTypeofIsAndBranch: public LControlInstruction<1, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001751 public:
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001752 explicit LTypeofIsAndBranch(LOperand* value) {
1753 inputs_[0] = value;
1754 }
1755
1756 DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch, "typeof-is-and-branch")
1757 DECLARE_HYDROGEN_ACCESSOR(TypeofIs)
1758
1759 Handle<String> type_literal() { return hydrogen()->type_literal(); }
1760
1761 virtual void PrintDataTo(StringStream* stream);
1762};
1763
1764
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001765class LDeleteProperty: public LTemplateInstruction<1, 2, 0> {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001766 public:
1767 LDeleteProperty(LOperand* obj, LOperand* key) {
1768 inputs_[0] = obj;
1769 inputs_[1] = key;
1770 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001771
1772 DECLARE_CONCRETE_INSTRUCTION(DeleteProperty, "delete-property")
1773
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001774 LOperand* object() { return inputs_[0]; }
1775 LOperand* key() { return inputs_[1]; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001776};
1777
1778
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001779class LOsrEntry: public LTemplateInstruction<0, 0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001780 public:
1781 LOsrEntry();
1782
1783 DECLARE_CONCRETE_INSTRUCTION(OsrEntry, "osr-entry")
1784
1785 LOperand** SpilledRegisterArray() { return register_spills_; }
1786 LOperand** SpilledDoubleRegisterArray() { return double_register_spills_; }
1787
1788 void MarkSpilledRegister(int allocation_index, LOperand* spill_operand);
1789 void MarkSpilledDoubleRegister(int allocation_index,
1790 LOperand* spill_operand);
1791
1792 private:
1793 // Arrays of spill slot operands for registers with an assigned spill
1794 // slot, i.e., that must also be restored to the spill slot on OSR entry.
1795 // NULL if the register has no assigned spill slot. Indexed by allocation
1796 // index.
1797 LOperand* register_spills_[Register::kNumAllocatableRegisters];
1798 LOperand* double_register_spills_[DoubleRegister::kNumAllocatableRegisters];
1799};
1800
1801
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001802class LStackCheck: public LTemplateInstruction<0, 0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001803 public:
1804 DECLARE_CONCRETE_INSTRUCTION(StackCheck, "stack-check")
1805};
1806
1807
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001808class LChunkBuilder;
1809class LChunk: public ZoneObject {
1810 public:
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00001811 explicit LChunk(HGraph* graph)
1812 : spill_slot_count_(0),
1813 graph_(graph),
1814 instructions_(32),
1815 pointer_maps_(8),
1816 inlined_closures_(1) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001817
1818 int AddInstruction(LInstruction* instruction, HBasicBlock* block);
1819 LConstantOperand* DefineConstantOperand(HConstant* constant);
1820 Handle<Object> LookupLiteral(LConstantOperand* operand) const;
1821 Representation LookupLiteralRepresentation(LConstantOperand* operand) const;
1822
1823 int GetNextSpillIndex(bool is_double);
1824 LOperand* GetNextSpillSlot(bool is_double);
1825
1826 int ParameterAt(int index);
1827 int GetParameterStackSlot(int index) const;
1828 int spill_slot_count() const { return spill_slot_count_; }
1829 HGraph* graph() const { return graph_; }
1830 const ZoneList<LInstruction*>* instructions() const { return &instructions_; }
1831 void AddGapMove(int index, LOperand* from, LOperand* to);
1832 LGap* GetGapAt(int index) const;
1833 bool IsGapAt(int index) const;
1834 int NearestGapPos(int index) const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001835 void MarkEmptyBlocks();
1836 const ZoneList<LPointerMap*>* pointer_maps() const { return &pointer_maps_; }
1837 LLabel* GetLabel(int block_id) const {
1838 HBasicBlock* block = graph_->blocks()->at(block_id);
1839 int first_instruction = block->first_instruction_index();
1840 return LLabel::cast(instructions_[first_instruction]);
1841 }
1842 int LookupDestination(int block_id) const {
1843 LLabel* cur = GetLabel(block_id);
1844 while (cur->replacement() != NULL) {
1845 cur = cur->replacement();
1846 }
1847 return cur->block_id();
1848 }
1849 Label* GetAssemblyLabel(int block_id) const {
1850 LLabel* label = GetLabel(block_id);
1851 ASSERT(!label->HasReplacement());
1852 return label->label();
1853 }
1854
1855 const ZoneList<Handle<JSFunction> >* inlined_closures() const {
1856 return &inlined_closures_;
1857 }
1858
1859 void AddInlinedClosure(Handle<JSFunction> closure) {
1860 inlined_closures_.Add(closure);
1861 }
1862
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001863 private:
1864 int spill_slot_count_;
1865 HGraph* const graph_;
1866 ZoneList<LInstruction*> instructions_;
1867 ZoneList<LPointerMap*> pointer_maps_;
1868 ZoneList<Handle<JSFunction> > inlined_closures_;
1869};
1870
1871
1872class LChunkBuilder BASE_EMBEDDED {
1873 public:
1874 LChunkBuilder(HGraph* graph, LAllocator* allocator)
1875 : chunk_(NULL),
1876 graph_(graph),
1877 status_(UNUSED),
1878 current_instruction_(NULL),
1879 current_block_(NULL),
1880 next_block_(NULL),
1881 argument_count_(0),
1882 allocator_(allocator),
1883 position_(RelocInfo::kNoPosition),
1884 instructions_pending_deoptimization_environment_(NULL),
1885 pending_deoptimization_ast_id_(AstNode::kNoNumber) { }
1886
1887 // Build the sequence for the graph.
1888 LChunk* Build();
1889
1890 // Declare methods that deal with the individual node types.
1891#define DECLARE_DO(type) LInstruction* Do##type(H##type* node);
1892 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_DO)
1893#undef DECLARE_DO
1894
1895 private:
1896 enum Status {
1897 UNUSED,
1898 BUILDING,
1899 DONE,
1900 ABORTED
1901 };
1902
1903 LChunk* chunk() const { return chunk_; }
1904 HGraph* graph() const { return graph_; }
1905
1906 bool is_unused() const { return status_ == UNUSED; }
1907 bool is_building() const { return status_ == BUILDING; }
1908 bool is_done() const { return status_ == DONE; }
1909 bool is_aborted() const { return status_ == ABORTED; }
1910
1911 void Abort(const char* format, ...);
1912
1913 // Methods for getting operands for Use / Define / Temp.
1914 LRegister* ToOperand(Register reg);
1915 LUnallocated* ToUnallocated(Register reg);
1916 LUnallocated* ToUnallocated(XMMRegister reg);
1917
1918 // Methods for setting up define-use relationships.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001919 MUST_USE_RESULT LOperand* Use(HValue* value, LUnallocated* operand);
1920 MUST_USE_RESULT LOperand* UseFixed(HValue* value, Register fixed_register);
1921 MUST_USE_RESULT LOperand* UseFixedDouble(HValue* value,
1922 XMMRegister fixed_register);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001923
1924 // A value that is guaranteed to be allocated to a register.
1925 // Operand created by UseRegister is guaranteed to be live until the end of
1926 // instruction. This means that register allocator will not reuse it's
1927 // register for any other operand inside instruction.
1928 // Operand created by UseRegisterAtStart is guaranteed to be live only at
1929 // instruction start. Register allocator is free to assign the same register
1930 // to some other operand used inside instruction (i.e. temporary or
1931 // output).
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001932 MUST_USE_RESULT LOperand* UseRegister(HValue* value);
1933 MUST_USE_RESULT LOperand* UseRegisterAtStart(HValue* value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001934
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001935 // An input operand in a register that may be trashed.
1936 MUST_USE_RESULT LOperand* UseTempRegister(HValue* value);
1937
1938 // An input operand in a register or stack slot.
1939 MUST_USE_RESULT LOperand* Use(HValue* value);
1940 MUST_USE_RESULT LOperand* UseAtStart(HValue* value);
1941
1942 // An input operand in a register, stack slot or a constant operand.
1943 MUST_USE_RESULT LOperand* UseOrConstant(HValue* value);
1944 MUST_USE_RESULT LOperand* UseOrConstantAtStart(HValue* value);
1945
1946 // An input operand in a register or a constant operand.
1947 MUST_USE_RESULT LOperand* UseRegisterOrConstant(HValue* value);
1948 MUST_USE_RESULT LOperand* UseRegisterOrConstantAtStart(HValue* value);
1949
1950 // An input operand in register, stack slot or a constant operand.
1951 // Will not be moved to a register even if one is freely available.
1952 MUST_USE_RESULT LOperand* UseAny(HValue* value);
1953
1954 // Temporary operand that must be in a register.
1955 MUST_USE_RESULT LUnallocated* TempRegister();
1956 MUST_USE_RESULT LOperand* FixedTemp(Register reg);
1957 MUST_USE_RESULT LOperand* FixedTemp(XMMRegister reg);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001958
1959 // Methods for setting up define-use relationships.
1960 // Return the same instruction that they are passed.
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001961 template<int I, int T>
1962 LInstruction* Define(LTemplateInstruction<1, I, T>* instr,
1963 LUnallocated* result);
1964 template<int I, int T>
1965 LInstruction* Define(LTemplateInstruction<1, I, T>* instr);
1966 template<int I, int T>
1967 LInstruction* DefineAsRegister(LTemplateInstruction<1, I, T>* instr);
1968 template<int I, int T>
1969 LInstruction* DefineAsSpilled(LTemplateInstruction<1, I, T>* instr,
1970 int index);
1971 template<int I, int T>
1972 LInstruction* DefineSameAsFirst(LTemplateInstruction<1, I, T>* instr);
1973 template<int I, int T>
1974 LInstruction* DefineFixed(LTemplateInstruction<1, I, T>* instr,
1975 Register reg);
1976 template<int I, int T>
1977 LInstruction* DefineFixedDouble(LTemplateInstruction<1, I, T>* instr,
1978 XMMRegister reg);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001979 LInstruction* AssignEnvironment(LInstruction* instr);
1980 LInstruction* AssignPointerMap(LInstruction* instr);
1981
1982 enum CanDeoptimize { CAN_DEOPTIMIZE_EAGERLY, CANNOT_DEOPTIMIZE_EAGERLY };
1983
1984 // By default we assume that instruction sequences generated for calls
1985 // cannot deoptimize eagerly and we do not attach environment to this
1986 // instruction.
1987 LInstruction* MarkAsCall(
1988 LInstruction* instr,
1989 HInstruction* hinstr,
1990 CanDeoptimize can_deoptimize = CANNOT_DEOPTIMIZE_EAGERLY);
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00001991 LInstruction* MarkAsSaveDoubles(LInstruction* instr);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001992
1993 LInstruction* SetInstructionPendingDeoptimizationEnvironment(
1994 LInstruction* instr, int ast_id);
1995 void ClearInstructionPendingDeoptimizationEnvironment();
1996
1997 LEnvironment* CreateEnvironment(HEnvironment* hydrogen_env);
1998
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001999 void VisitInstruction(HInstruction* current);
2000
2001 void DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block);
2002 LInstruction* DoBit(Token::Value op, HBitwiseBinaryOperation* instr);
2003 LInstruction* DoShift(Token::Value op, HBitwiseBinaryOperation* instr);
2004 LInstruction* DoArithmeticD(Token::Value op,
2005 HArithmeticBinaryOperation* instr);
2006 LInstruction* DoArithmeticT(Token::Value op,
2007 HArithmeticBinaryOperation* instr);
2008
2009 LChunk* chunk_;
2010 HGraph* const graph_;
2011 Status status_;
2012 HInstruction* current_instruction_;
2013 HBasicBlock* current_block_;
2014 HBasicBlock* next_block_;
2015 int argument_count_;
2016 LAllocator* allocator_;
2017 int position_;
2018 LInstruction* instructions_pending_deoptimization_environment_;
2019 int pending_deoptimization_ast_id_;
2020
2021 DISALLOW_COPY_AND_ASSIGN(LChunkBuilder);
2022};
2023
2024#undef DECLARE_HYDROGEN_ACCESSOR
2025#undef DECLARE_INSTRUCTION
2026#undef DECLARE_CONCRETE_INSTRUCTION
2027
2028} } // namespace v8::internal
2029
2030#endif // V8_IA32_LITHIUM_IA32_H_