| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 10 matching lines...) Expand all Loading... |
| 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_CODEGEN_ARM_H_ | 28 #ifndef V8_ARM_CODEGEN_ARM_H_ |
| 29 #define V8_ARM_CODEGEN_ARM_H_ | 29 #define V8_ARM_CODEGEN_ARM_H_ |
| 30 | 30 |
| 31 #include "ic-inl.h" | |
| 32 | |
| 33 namespace v8 { | 31 namespace v8 { |
| 34 namespace internal { | 32 namespace internal { |
| 35 | 33 |
| 36 // Forward declarations | 34 // Forward declarations |
| 37 class CompilationInfo; | 35 class CompilationInfo; |
| 38 class DeferredCode; | 36 class DeferredCode; |
| 39 class RegisterAllocator; | 37 class RegisterAllocator; |
| 40 class RegisterFile; | 38 class RegisterFile; |
| 41 | 39 |
| 42 enum InitState { CONST_INIT, NOT_CONST_INIT }; | 40 enum InitState { CONST_INIT, NOT_CONST_INIT }; |
| (...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 467 | 465 |
| 468 class GenericBinaryOpStub : public CodeStub { | 466 class GenericBinaryOpStub : public CodeStub { |
| 469 public: | 467 public: |
| 470 GenericBinaryOpStub(Token::Value op, | 468 GenericBinaryOpStub(Token::Value op, |
| 471 OverwriteMode mode, | 469 OverwriteMode mode, |
| 472 int constant_rhs = CodeGenerator::kUnknownIntValue) | 470 int constant_rhs = CodeGenerator::kUnknownIntValue) |
| 473 : op_(op), | 471 : op_(op), |
| 474 mode_(mode), | 472 mode_(mode), |
| 475 constant_rhs_(constant_rhs), | 473 constant_rhs_(constant_rhs), |
| 476 specialized_on_rhs_(RhsIsOneWeWantToOptimizeFor(op, constant_rhs)), | 474 specialized_on_rhs_(RhsIsOneWeWantToOptimizeFor(op, constant_rhs)), |
| 477 runtime_operands_type_(BinaryOpIC::DEFAULT), | |
| 478 name_(NULL) { } | |
| 479 | |
| 480 GenericBinaryOpStub(int key, BinaryOpIC::TypeInfo type_info) | |
| 481 : op_(OpBits::decode(key)), | |
| 482 mode_(ModeBits::decode(key)), | |
| 483 constant_rhs_(KnownBitsForMinorKey(KnownIntBits::decode(key))), | |
| 484 specialized_on_rhs_(RhsIsOneWeWantToOptimizeFor(op_, constant_rhs_)), | |
| 485 runtime_operands_type_(type_info), | |
| 486 name_(NULL) { } | 475 name_(NULL) { } |
| 487 | 476 |
| 488 private: | 477 private: |
| 489 Token::Value op_; | 478 Token::Value op_; |
| 490 OverwriteMode mode_; | 479 OverwriteMode mode_; |
| 491 int constant_rhs_; | 480 int constant_rhs_; |
| 492 bool specialized_on_rhs_; | 481 bool specialized_on_rhs_; |
| 493 BinaryOpIC::TypeInfo runtime_operands_type_; | |
| 494 char* name_; | 482 char* name_; |
| 495 | 483 |
| 496 static const int kMaxKnownRhs = 0x40000000; | 484 static const int kMaxKnownRhs = 0x40000000; |
| 497 | 485 |
| 498 // Minor key encoding in 18 bits. | 486 // Minor key encoding in 16 bits. |
| 499 class ModeBits: public BitField<OverwriteMode, 0, 2> {}; | 487 class ModeBits: public BitField<OverwriteMode, 0, 2> {}; |
| 500 class OpBits: public BitField<Token::Value, 2, 6> {}; | 488 class OpBits: public BitField<Token::Value, 2, 6> {}; |
| 501 class KnownIntBits: public BitField<int, 8, 8> {}; | 489 class KnownIntBits: public BitField<int, 8, 8> {}; |
| 502 class TypeInfoBits: public BitField<int, 16, 2> {}; | |
| 503 | 490 |
| 504 Major MajorKey() { return GenericBinaryOp; } | 491 Major MajorKey() { return GenericBinaryOp; } |
| 505 int MinorKey() { | 492 int MinorKey() { |
| 506 // Encode the parameters in a unique 18 bit value. | 493 // Encode the parameters in a unique 16 bit value. |
| 507 return OpBits::encode(op_) | 494 return OpBits::encode(op_) |
| 508 | ModeBits::encode(mode_) | 495 | ModeBits::encode(mode_) |
| 509 | KnownIntBits::encode(MinorKeyForKnownInt()) | 496 | KnownIntBits::encode(MinorKeyForKnownInt()); |
| 510 | TypeInfoBits::encode(runtime_operands_type_); | |
| 511 } | 497 } |
| 512 | 498 |
| 513 void Generate(MacroAssembler* masm); | 499 void Generate(MacroAssembler* masm); |
| 514 void HandleNonSmiBitwiseOp(MacroAssembler* masm); | 500 void HandleNonSmiBitwiseOp(MacroAssembler* masm); |
| 515 void HandleBinaryOpSlowCases(MacroAssembler* masm, | |
| 516 Label* not_smi, | |
| 517 const Builtins::JavaScript& builtin); | |
| 518 void GenerateTypeTransition(MacroAssembler* masm); | |
| 519 | 501 |
| 520 static bool RhsIsOneWeWantToOptimizeFor(Token::Value op, int constant_rhs) { | 502 static bool RhsIsOneWeWantToOptimizeFor(Token::Value op, int constant_rhs) { |
| 521 if (constant_rhs == CodeGenerator::kUnknownIntValue) return false; | 503 if (constant_rhs == CodeGenerator::kUnknownIntValue) return false; |
| 522 if (op == Token::DIV) return constant_rhs >= 2 && constant_rhs <= 3; | 504 if (op == Token::DIV) return constant_rhs >= 2 && constant_rhs <= 3; |
| 523 if (op == Token::MOD) { | 505 if (op == Token::MOD) { |
| 524 if (constant_rhs <= 1) return false; | 506 if (constant_rhs <= 1) return false; |
| 525 if (constant_rhs <= 10) return true; | 507 if (constant_rhs <= 10) return true; |
| 526 if (constant_rhs <= kMaxKnownRhs && IsPowerOf2(constant_rhs)) return true; | 508 if (constant_rhs <= kMaxKnownRhs && IsPowerOf2(constant_rhs)) return true; |
| 527 return false; | 509 return false; |
| 528 } | 510 } |
| 529 return false; | 511 return false; |
| 530 } | 512 } |
| 531 | 513 |
| 532 int MinorKeyForKnownInt() { | 514 int MinorKeyForKnownInt() { |
| 533 if (!specialized_on_rhs_) return 0; | 515 if (!specialized_on_rhs_) return 0; |
| 534 if (constant_rhs_ <= 10) return constant_rhs_ + 1; | 516 if (constant_rhs_ <= 10) return constant_rhs_ + 1; |
| 535 ASSERT(IsPowerOf2(constant_rhs_)); | 517 ASSERT(IsPowerOf2(constant_rhs_)); |
| 536 int key = 12; | 518 int key = 12; |
| 537 int d = constant_rhs_; | 519 int d = constant_rhs_; |
| 538 while ((d & 1) == 0) { | 520 while ((d & 1) == 0) { |
| 539 key++; | 521 key++; |
| 540 d >>= 1; | 522 d >>= 1; |
| 541 } | 523 } |
| 542 return key; | 524 return key; |
| 543 } | 525 } |
| 544 | 526 |
| 545 int KnownBitsForMinorKey(int key) { | |
| 546 if (!key) return 0; | |
| 547 if (key <= 11) return key - 1; | |
| 548 int d = 1; | |
| 549 while (key != 12) { | |
| 550 key--; | |
| 551 d <<= 1; | |
| 552 } | |
| 553 return d; | |
| 554 } | |
| 555 | |
| 556 bool ShouldGenerateSmiCode() { | |
| 557 return ((op_ != Token::DIV && op_ != Token::MOD) || specialized_on_rhs_) && | |
| 558 runtime_operands_type_ != BinaryOpIC::HEAP_NUMBERS && | |
| 559 runtime_operands_type_ != BinaryOpIC::STRINGS; | |
| 560 } | |
| 561 | |
| 562 bool ShouldGenerateFPCode() { | |
| 563 return runtime_operands_type_ != BinaryOpIC::STRINGS; | |
| 564 } | |
| 565 | |
| 566 virtual int GetCodeKind() { return Code::BINARY_OP_IC; } | |
| 567 | |
| 568 virtual InlineCacheState GetICState() { | |
| 569 return BinaryOpIC::ToState(runtime_operands_type_); | |
| 570 } | |
| 571 | |
| 572 const char* GetName(); | 527 const char* GetName(); |
| 573 | 528 |
| 574 #ifdef DEBUG | 529 #ifdef DEBUG |
| 575 void Print() { | 530 void Print() { |
| 576 if (!specialized_on_rhs_) { | 531 if (!specialized_on_rhs_) { |
| 577 PrintF("GenericBinaryOpStub (%s)\n", Token::String(op_)); | 532 PrintF("GenericBinaryOpStub (%s)\n", Token::String(op_)); |
| 578 } else { | 533 } else { |
| 579 PrintF("GenericBinaryOpStub (%s by %d)\n", | 534 PrintF("GenericBinaryOpStub (%s by %d)\n", |
| 580 Token::String(op_), | 535 Token::String(op_), |
| 581 constant_rhs_); | 536 constant_rhs_); |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 734 void Print() { | 689 void Print() { |
| 735 PrintF("NumberToStringStub\n"); | 690 PrintF("NumberToStringStub\n"); |
| 736 } | 691 } |
| 737 #endif | 692 #endif |
| 738 }; | 693 }; |
| 739 | 694 |
| 740 | 695 |
| 741 } } // namespace v8::internal | 696 } } // namespace v8::internal |
| 742 | 697 |
| 743 #endif // V8_ARM_CODEGEN_ARM_H_ | 698 #endif // V8_ARM_CODEGEN_ARM_H_ |
| OLD | NEW |