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

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

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