OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
136 V(MathFloorOfDiv) \ | 136 V(MathFloorOfDiv) \ |
137 V(MathLog) \ | 137 V(MathLog) \ |
138 V(MathMinMax) \ | 138 V(MathMinMax) \ |
139 V(MathPowHalf) \ | 139 V(MathPowHalf) \ |
140 V(MathRound) \ | 140 V(MathRound) \ |
141 V(MathSin) \ | 141 V(MathSin) \ |
142 V(MathSqrt) \ | 142 V(MathSqrt) \ |
143 V(MathTan) \ | 143 V(MathTan) \ |
144 V(ModI) \ | 144 V(ModI) \ |
145 V(MulI) \ | 145 V(MulI) \ |
146 V(NegateNoSSE2D) \ | |
147 V(NumberTagD) \ | 146 V(NumberTagD) \ |
148 V(NumberTagI) \ | 147 V(NumberTagI) \ |
149 V(NumberTagU) \ | 148 V(NumberTagU) \ |
150 V(NumberUntagD) \ | 149 V(NumberUntagD) \ |
151 V(OsrEntry) \ | 150 V(OsrEntry) \ |
152 V(OuterContext) \ | 151 V(OuterContext) \ |
153 V(Parameter) \ | 152 V(Parameter) \ |
154 V(Power) \ | 153 V(Power) \ |
155 V(Random) \ | 154 V(Random) \ |
156 V(PushArgument) \ | 155 V(PushArgument) \ |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
260 HValue* hydrogen_value() const { return hydrogen_value_; } | 259 HValue* hydrogen_value() const { return hydrogen_value_; } |
261 | 260 |
262 virtual void SetDeferredLazyDeoptimizationEnvironment(LEnvironment* env) { } | 261 virtual void SetDeferredLazyDeoptimizationEnvironment(LEnvironment* env) { } |
263 | 262 |
264 void MarkAsCall() { is_call_ = true; } | 263 void MarkAsCall() { is_call_ = true; } |
265 | 264 |
266 // Interface to the register allocator and iterators. | 265 // Interface to the register allocator and iterators. |
267 bool ClobbersTemps() const { return is_call_; } | 266 bool ClobbersTemps() const { return is_call_; } |
268 bool ClobbersRegisters() const { return is_call_; } | 267 bool ClobbersRegisters() const { return is_call_; } |
269 virtual bool ClobbersDoubleRegisters() const { | 268 virtual bool ClobbersDoubleRegisters() const { |
270 return is_call_ || !CpuFeatures::IsSupported(SSE2); | 269 return is_call_ || |
| 270 (!CpuFeatures::IsSupported(SSE2) && |
| 271 // We only have rudimentary X87Stack tracking, thus in general |
| 272 // cannot handle deoptimization nor phi-nodes. |
| 273 (HasEnvironment() || IsControl())); |
271 } | 274 } |
272 | 275 |
273 virtual bool HasResult() const = 0; | 276 virtual bool HasResult() const = 0; |
274 virtual LOperand* result() = 0; | 277 virtual LOperand* result() = 0; |
275 | 278 |
276 bool HasDoubleRegisterResult(); | 279 bool HasDoubleRegisterResult(); |
277 bool HasDoubleRegisterInput(); | 280 bool HasDoubleRegisterInput(); |
| 281 bool IsDoubleInput(X87Register reg, LCodeGen* cgen); |
278 | 282 |
279 LOperand* FirstInput() { return InputAt(0); } | 283 LOperand* FirstInput() { return InputAt(0); } |
280 LOperand* Output() { return HasResult() ? result() : NULL; } | 284 LOperand* Output() { return HasResult() ? result() : NULL; } |
281 | 285 |
282 virtual bool HasInterestingComment(LCodeGen* gen) const { return true; } | 286 virtual bool HasInterestingComment(LCodeGen* gen) const { return true; } |
283 | 287 |
284 #ifdef DEBUG | 288 #ifdef DEBUG |
285 void VerifyCall(); | 289 void VerifyCall(); |
286 #endif | 290 #endif |
287 | 291 |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
372 | 376 |
373 private: | 377 private: |
374 LParallelMove* parallel_moves_[LAST_INNER_POSITION + 1]; | 378 LParallelMove* parallel_moves_[LAST_INNER_POSITION + 1]; |
375 HBasicBlock* block_; | 379 HBasicBlock* block_; |
376 }; | 380 }; |
377 | 381 |
378 | 382 |
379 class LInstructionGap: public LGap { | 383 class LInstructionGap: public LGap { |
380 public: | 384 public: |
381 explicit LInstructionGap(HBasicBlock* block) : LGap(block) { } | 385 explicit LInstructionGap(HBasicBlock* block) : LGap(block) { } |
382 virtual bool ClobbersDoubleRegisters() const { return false; } | |
383 | 386 |
384 virtual bool HasInterestingComment(LCodeGen* gen) const { | 387 virtual bool HasInterestingComment(LCodeGen* gen) const { |
385 return !IsRedundant(); | 388 return !IsRedundant(); |
386 } | 389 } |
387 | 390 |
388 DECLARE_CONCRETE_INSTRUCTION(InstructionGap, "gap") | 391 DECLARE_CONCRETE_INSTRUCTION(InstructionGap, "gap") |
389 }; | 392 }; |
390 | 393 |
391 | 394 |
392 class LGoto: public LTemplateInstruction<0, 0, 0> { | 395 class LGoto: public LTemplateInstruction<0, 0, 0> { |
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
654 | 657 |
655 LOperand* left() { return inputs_[0]; } | 658 LOperand* left() { return inputs_[0]; } |
656 LOperand* right() { return inputs_[1]; } | 659 LOperand* right() { return inputs_[1]; } |
657 LOperand* temp() { return temps_[0]; } | 660 LOperand* temp() { return temps_[0]; } |
658 | 661 |
659 DECLARE_CONCRETE_INSTRUCTION(MathFloorOfDiv, "math-floor-of-div") | 662 DECLARE_CONCRETE_INSTRUCTION(MathFloorOfDiv, "math-floor-of-div") |
660 DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv) | 663 DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv) |
661 }; | 664 }; |
662 | 665 |
663 | 666 |
664 class LNegateNoSSE2D: public LTemplateInstruction<1, 1, 0> { | |
665 public: | |
666 explicit LNegateNoSSE2D(LOperand* value) { | |
667 inputs_[0] = value; | |
668 } | |
669 | |
670 LOperand* value() { return inputs_[0]; } | |
671 | |
672 DECLARE_CONCRETE_INSTRUCTION(NegateNoSSE2D, "negate-no-sse2-d") | |
673 }; | |
674 | |
675 | |
676 class LMulI: public LTemplateInstruction<1, 2, 1> { | 667 class LMulI: public LTemplateInstruction<1, 2, 1> { |
677 public: | 668 public: |
678 LMulI(LOperand* left, LOperand* right, LOperand* temp) { | 669 LMulI(LOperand* left, LOperand* right, LOperand* temp) { |
679 inputs_[0] = left; | 670 inputs_[0] = left; |
680 inputs_[1] = right; | 671 inputs_[1] = right; |
681 temps_[0] = temp; | 672 temps_[0] = temp; |
682 } | 673 } |
683 | 674 |
684 LOperand* left() { return inputs_[0]; } | 675 LOperand* left() { return inputs_[0]; } |
685 LOperand* right() { return inputs_[1]; } | 676 LOperand* right() { return inputs_[1]; } |
(...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1217 Smi* value() const { return Smi::FromInt(hydrogen()->Integer32Value()); } | 1208 Smi* value() const { return Smi::FromInt(hydrogen()->Integer32Value()); } |
1218 }; | 1209 }; |
1219 | 1210 |
1220 | 1211 |
1221 class LConstantD: public LTemplateInstruction<1, 0, 1> { | 1212 class LConstantD: public LTemplateInstruction<1, 0, 1> { |
1222 public: | 1213 public: |
1223 explicit LConstantD(LOperand* temp) { | 1214 explicit LConstantD(LOperand* temp) { |
1224 temps_[0] = temp; | 1215 temps_[0] = temp; |
1225 } | 1216 } |
1226 | 1217 |
1227 virtual bool ClobbersDoubleRegisters() const { | |
1228 return false; | |
1229 } | |
1230 | |
1231 LOperand* temp() { return temps_[0]; } | 1218 LOperand* temp() { return temps_[0]; } |
1232 | 1219 |
1233 DECLARE_CONCRETE_INSTRUCTION(ConstantD, "constant-d") | 1220 DECLARE_CONCRETE_INSTRUCTION(ConstantD, "constant-d") |
1234 DECLARE_HYDROGEN_ACCESSOR(Constant) | 1221 DECLARE_HYDROGEN_ACCESSOR(Constant) |
1235 | 1222 |
1236 double value() const { return hydrogen()->DoubleValue(); } | 1223 double value() const { return hydrogen()->DoubleValue(); } |
1237 }; | 1224 }; |
1238 | 1225 |
1239 | 1226 |
1240 class LConstantT: public LTemplateInstruction<1, 0, 0> { | 1227 class LConstantT: public LTemplateInstruction<1, 0, 0> { |
(...skipping 960 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2201 class LNumberUntagD: public LTemplateInstruction<1, 1, 1> { | 2188 class LNumberUntagD: public LTemplateInstruction<1, 1, 1> { |
2202 public: | 2189 public: |
2203 explicit LNumberUntagD(LOperand* value, LOperand* temp) { | 2190 explicit LNumberUntagD(LOperand* value, LOperand* temp) { |
2204 inputs_[0] = value; | 2191 inputs_[0] = value; |
2205 temps_[0] = temp; | 2192 temps_[0] = temp; |
2206 } | 2193 } |
2207 | 2194 |
2208 LOperand* value() { return inputs_[0]; } | 2195 LOperand* value() { return inputs_[0]; } |
2209 LOperand* temp() { return temps_[0]; } | 2196 LOperand* temp() { return temps_[0]; } |
2210 | 2197 |
2211 virtual bool ClobbersDoubleRegisters() const { | 2198 virtual bool ClobbersDoubleRegisters() const { return false; } |
2212 return false; | |
2213 } | |
2214 | 2199 |
2215 DECLARE_CONCRETE_INSTRUCTION(NumberUntagD, "double-untag") | 2200 DECLARE_CONCRETE_INSTRUCTION(NumberUntagD, "double-untag") |
2216 DECLARE_HYDROGEN_ACCESSOR(Change); | 2201 DECLARE_HYDROGEN_ACCESSOR(Change); |
2217 }; | 2202 }; |
2218 | 2203 |
2219 | 2204 |
2220 class LSmiUntag: public LTemplateInstruction<1, 1, 0> { | 2205 class LSmiUntag: public LTemplateInstruction<1, 1, 0> { |
2221 public: | 2206 public: |
2222 LSmiUntag(LOperand* value, bool needs_check) | 2207 LSmiUntag(LOperand* value, bool needs_check) |
2223 : needs_check_(needs_check) { | 2208 : needs_check_(needs_check) { |
(...skipping 655 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2879 bool is_unused() const { return status_ == UNUSED; } | 2864 bool is_unused() const { return status_ == UNUSED; } |
2880 bool is_building() const { return status_ == BUILDING; } | 2865 bool is_building() const { return status_ == BUILDING; } |
2881 bool is_done() const { return status_ == DONE; } | 2866 bool is_done() const { return status_ == DONE; } |
2882 bool is_aborted() const { return status_ == ABORTED; } | 2867 bool is_aborted() const { return status_ == ABORTED; } |
2883 | 2868 |
2884 void Abort(const char* reason); | 2869 void Abort(const char* reason); |
2885 | 2870 |
2886 // Methods for getting operands for Use / Define / Temp. | 2871 // Methods for getting operands for Use / Define / Temp. |
2887 LUnallocated* ToUnallocated(Register reg); | 2872 LUnallocated* ToUnallocated(Register reg); |
2888 LUnallocated* ToUnallocated(XMMRegister reg); | 2873 LUnallocated* ToUnallocated(XMMRegister reg); |
2889 LUnallocated* ToUnallocated(X87TopOfStackRegister reg); | 2874 LUnallocated* ToUnallocated(X87Register reg); |
2890 | 2875 |
2891 // Methods for setting up define-use relationships. | 2876 // Methods for setting up define-use relationships. |
2892 MUST_USE_RESULT LOperand* Use(HValue* value, LUnallocated* operand); | 2877 MUST_USE_RESULT LOperand* Use(HValue* value, LUnallocated* operand); |
2893 MUST_USE_RESULT LOperand* UseFixed(HValue* value, Register fixed_register); | 2878 MUST_USE_RESULT LOperand* UseFixed(HValue* value, Register fixed_register); |
2894 MUST_USE_RESULT LOperand* UseFixedDouble(HValue* value, | 2879 MUST_USE_RESULT LOperand* UseFixedDouble(HValue* value, |
2895 XMMRegister fixed_register); | 2880 XMMRegister fixed_register); |
2896 MUST_USE_RESULT LOperand* UseX87TopOfStack(HValue* value); | |
2897 | 2881 |
2898 // A value that is guaranteed to be allocated to a register. | 2882 // A value that is guaranteed to be allocated to a register. |
2899 // Operand created by UseRegister is guaranteed to be live until the end of | 2883 // Operand created by UseRegister is guaranteed to be live until the end of |
2900 // instruction. This means that register allocator will not reuse it's | 2884 // instruction. This means that register allocator will not reuse it's |
2901 // register for any other operand inside instruction. | 2885 // register for any other operand inside instruction. |
2902 // Operand created by UseRegisterAtStart is guaranteed to be live only at | 2886 // Operand created by UseRegisterAtStart is guaranteed to be live only at |
2903 // instruction start. Register allocator is free to assign the same register | 2887 // instruction start. Register allocator is free to assign the same register |
2904 // to some other operand used inside instruction (i.e. temporary or | 2888 // to some other operand used inside instruction (i.e. temporary or |
2905 // output). | 2889 // output). |
2906 MUST_USE_RESULT LOperand* UseRegister(HValue* value); | 2890 MUST_USE_RESULT LOperand* UseRegister(HValue* value); |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3000 | 2984 |
3001 DISALLOW_COPY_AND_ASSIGN(LChunkBuilder); | 2985 DISALLOW_COPY_AND_ASSIGN(LChunkBuilder); |
3002 }; | 2986 }; |
3003 | 2987 |
3004 #undef DECLARE_HYDROGEN_ACCESSOR | 2988 #undef DECLARE_HYDROGEN_ACCESSOR |
3005 #undef DECLARE_CONCRETE_INSTRUCTION | 2989 #undef DECLARE_CONCRETE_INSTRUCTION |
3006 | 2990 |
3007 } } // namespace v8::internal | 2991 } } // namespace v8::internal |
3008 | 2992 |
3009 #endif // V8_IA32_LITHIUM_IA32_H_ | 2993 #endif // V8_IA32_LITHIUM_IA32_H_ |
OLD | NEW |