Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(108)

Side by Side Diff: src/a64/lithium-a64.h

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

Powered by Google App Engine
This is Rietveld 408576698