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